Using SUM & GROUP BY on Collection in Linq - c#

I want to use SUM & GOUP BY in linq. I have records in a collection & want to use the below query to execute on the collection by linq
public class Summary
{
public int Month { get; set; }
public int Year { get; set; }
public double Wages { get; set; }
public double AccNo22 { get; set; }
public double AccNo21 { get; set; }
}
List<Summary> list = new List<Summary>();
for (int i = 0; i < data.Rows.Count; i++)
{
Summary model = new Summary();
model.Month = int.Parse(data.Rows[i]["MonthNumber"].ToString());
model.Year = int.Parse(data.Rows[i]["Year"].ToString());
model.AccNo22 = 0;
model.AccNo21 = 0;
list.Add(model);
}
Query :-
SELECT Year, Month, SUM(ACCNO21) AS ACC21,SUM(ACCNO22) AS ACC22 FROM AboveList
WHERE (((Month >= 3 AND Month <= 12) AND Year = '2015') OR ((Month >= 1 AND Month <= 2) AND Year = '2016'))
GROUP BY Month,Year")
I am trying :-
var newCollection = list
.GroupBy(a => a.Month, b => b.Year)
.Select(a => new { Wages = a.Sum(a.Wages)})
.ToList();

Well, you can filter on list first, then group by and select elements.
var newCollection = list
.Where(m => (m.Month >= 3 && m.Month <=12 && m.Year == 2015) ||
(m.Month >=1 && m.Month <=2 && m.Year == 2016)
)
.GroupBy(m => new{m.Month, m.Year})
.Select(m => new {
year = m.Key.Year,
month = m.Key.Month,
AccNo21 = m.Sum(g => g.AccNo21),
AccNo22 = m.Sum(g => g.AccNo22)
});

You need to project it like this:-
.Select(a => new { Wages = a.Sum(b => b.Wages)})
and so on for AccNo22, AccNo21 etc.
Here is the complete query:-
var result= list.Where(x => (x.Month >= 3 && x.Month <=12 && x.Year == 2015) ||
(x.Month >=1 && x.Month <=2 && x.Year == 2016)
)
.GroupBy(x => new {x.Month, x.Year})
.Select(x => new {
Year = x.Key.Year,
Month = x.Key.Month,
AccNo21 = x.Sum(z => z.AccNo21),
AccNo22 = x.Sum(z => z.AccNo22)
});

Related

I want to divide model's component by another component in .NET Core

Here is my model:
int YearNo { get; set; }
double Nights { get; set; }
double Visits { get; set; }
I want to divide Nights on Visits to get per night in a year and then return it by API.
this is my repository:
var datas = mapper.Map<List<ILocalDefaultIndicatorNights>>(records);
List<ILocalDefaultIndicatorNights> filteredData = new List<ILocalDefaultIndicatorNights>();
for (int i = 0; i < datas.Count; i++)
{
if (!filteredData.Exists(o => o.YearNo == datas[i].YearNo))
{
for (int x = 0; x < datas.Count; x++)
{
if (datas[i].YearNo == datas[x].YearNo && datas[i] != datas[x])
{
datas[i].Visits += datas[x].Visits;
var obj = filteredData.FirstOrDefault(o => o.YearNo == datas[i].YearNo);
if (obj != null)
obj.Visits = datas[i].Visits;
else
filteredData.Add(datas[i]);
}
}
}
}
return filteredData.OrderBy(i => i.YearNo).ToList();
How is it possible to do?
When I understand you right, then you want to do something like the following. But first I think your code could also be expressed like this:
List<LocalDefaultIndicatorNights> visitsPerYear = datas
.GroupBy(x => x.YearNo)
.Select(g => new LocalDefaultIndicatorNights()
{
YearNo = g.Key,
Nights = g.First().Nights,
Visits = g.Select(x1 => x1.Visits).Sum(),
})
.OrderBy(y => y.YearNo)
.ToList();
The visits per night in each year then can be calculated like this:
Dictionary<int, double> visitsPerNightsForEachYear = visitsPerYear.Select(v =>
{
double visitsPerNights = v.Visits / v.Nights;
return new KeyValuePair<int, double>(v.YearNo, visitsPerNights);
})
.ToDictionary(x => x.Key, x => x.Value);

Increment outer loop from inner loop in C# using Foreach

I am trying to search through a group of days, and determine if a worker has worked that day, and get a total of days worked. The below works, but is terribly inefficient since even after it finds a guy worked a day it keeps looking through the rest of those days. If I could somehow increment the outer ForEach loop when the inner condition (day worked) is satisfied it would surely be faster.
totalDaysWorked is what I'm after below:
public class StationSupportRequest
{
public string RequestNum;
public string Status;
public string Prefix;
public string PlantLoc;
public DateTime Date;
public string Departmnt;
public DateTime Time;
public string StationID;
public string Fixture;
public string Supervisor;
public string PartNo;
public string SerialNum;
public string FailedStep;
public string Reason;
public string OtherReason;
public string Details;
public string Urgency;
public DateTime Date_1;
public DateTime Time_1;
public DateTime Date_2;
public DateTime Time_2;
public string ProblemFound;
public string SolutionCode;
public string Solution;
public double ServiceTechHrs;
public double ServiceEngHrs;
public string DocHistory;
public DateTime CloseDate;
public DateTime IniDate;
public DateTime IniTime;
public string MOT;
public string Initiator;
public string Notification;
public string ServiceTech;
public string ServiceEng;
public string SolutionCode_1;
public string Solution_1;
public string UpdatedBy;
public List<string> UpdatedByList;
public string Revisions;
public List<DateTime> RevisionsDateTime;
public List<WorkedDatapoint> WorkedDataPointsList;
}
public class WorkedDatapoint
{
public string AssignerName { get; set; }
public string AssigneeName { get; set; }
public DateTime Date { get; set; }
public bool AssignedToOther { get; set; }
}
var DateRange = SSRList.Where(y => y.IniDate >= IniDate && y.CloseDate < EndDate);
//DateRange = DateRange.Where(dr => dr.Fixture != null && dr.Fixture.Length == 6); //To get valid fixtures if pivoting on "Fixture"
var groupedData = DateRange.GroupBy(x => new { DS = x.ServiceTech }).Select(x =>
{
double totalSsrsWorkedOn = x.Select(y => y.RequestNum).Count();
IEnumerable<TimeSpan> hoursWorked = x.Select(y => y.CloseDate - y.IniDate.AddDays(GetWeekendDaysToSubtract(y.IniDate, y.CloseDate)));
var averageReactionTimeMinutes = x.Where(d => d.IniDate != null && d.Revisions != null)
.Average(d => ((DateTime.Parse(d.Revisions.Split(',')[0]) - (DateTime)d.IniDate)).Minutes);
double[] listOfMinutesOpenTime = x.Where(d => d.IniDate != null && d.Revisions != null)
.Select(d => Convert.ToDouble(((DateTime.Parse(d.Revisions.Split(',')[0]) - (DateTime)d.IniDate)).Minutes))
.ToArray();
double[] listOfDaysOpenTime = x.Where(d => d.IniDate != null && d.CloseDate != null)
.Select(d => ((DateTime)d.CloseDate - (DateTime)d.IniDate.AddDays(GetWeekendDaysToSubtract(d.IniDate, d.CloseDate))).TotalDays)
.ToArray();
string testtech = x.Select(y => y.ServiceTech).FirstOrDefault();
List<DateTime> totalDaysInDateRange = Enumerable.Range(0, 1 + EndDate.Subtract(IniDate).Days)
.Select(offset => IniDate.AddDays(offset)).ToList();
double totalHoursLogged = x.Sum(d => d.ServiceEngHrs) + x.Sum(d => d.ServiceTechHrs);
int assignedToOthersCount = x.SelectMany(y => y.WorkedDataPointsList)
.Where(z => z.AssignerName.Contains(testtech) && z.AssignedToOther == true)
.Count();
int brokenWiresFixed = x.Where(d => d.SolutionCode != null)
.Where(d => d.SolutionCode.Contains("A01 -") ||
d.SolutionCode.Contains("F01 -") ||
d.SolutionCode.Contains("S01 -")).Count();
int npfResults = x.Where(d => d.ProblemFound != null).Where(d => d.ProblemFound.Contains("NPF")).Count();
int totalDaysWorked = 0;
List<DateTime> workingDatesList = new List<DateTime>();
totalDaysInDateRange.ForEach((day) =>
{
x.Select(y => y.WorkedDataPointsList).ForEach((WorkedDataPoint) =>
{
IEnumerable<WorkedDatapoint> dateList = WorkedDataPoint
.Where(y => testtech == y.AssignerName)
.DistinctBy(z => z.Date.Date);
foreach ( WorkedDatapoint date in dateList)
{
if (x.Any(b => b.Date.Date.Date == date.Date.Date.Date))
{
workingDatesList.Add(date.Date.Date.Date);
break;
}
}
});
});
workingDatesList.Dump("WorkingDatesList");
totalDaysWorked = workingDatesList.DistinctBy(b => b.Date).Count();
/*int totalDaysWorked = 0;
totalDaysInDateRange.ForEach((day) =>
{
if (AssignersList.Where(d => testtech.Contains(d.AssignerName))
.DistinctBy(d => d.Date.Date)
.Any(d => d.Date.Date == day.Date))
{
totalDaysWorked++;
}
}); TODO: Delete this once new is working*/
return new
{
//SSRs = x,
//Station = x.Select(d => d.StationID).FirstOrDefault(),
//Fixture = x.Select(d => d.Fixture).FirstOrDefault(),
//ProductTested = x.Select(d => d.Details).FirstOrDefault(),
TestTech = testtech,
//TestEng = x.Select(d => d.ServiceEng).Distinct().Where(d => d.Length > 0),
TotalSSRsWorkedOn = Math.Round(totalSsrsWorkedOn, 4),
TotalHoursLogged = Math.Round(totalHoursLogged, 4),
AssignedToOthersCount = assignedToOthersCount,
AssignedToOthersPercentage = 100 * Math.Round(assignedToOthersCount / (assignedToOthersCount + totalSsrsWorkedOn), 4),
//AverageReactionTimeMinutes = averageReactionTimeMinutes,
AverageTimeToCompleteHours = x.Where(y => y.CloseDate != null && y.Time_1 != null && y.Time_1 != DateTime.MinValue).Select(z => (z.CloseDate - z.Time_1).TotalHours).Average(),
//Close = x.Where(y => y.CloseDate != null && y.Time_1 != null).Select(z => (z.CloseDate)),
//Time = x.Where(y => y.CloseDate != null && y.Time_1 != null).Select(z => (z.Time_1)),
MedianDaysRequestOpen = Math.Round(GetMedian(listOfDaysOpenTime), 3),
DaysWorkedPerDateRange = totalDaysWorked,
AveSSRsClosedPerWorkedDay = Math.Round(totalSsrsWorkedOn / totalDaysWorked, 3),
AveHoursLoggedPerRequest = Math.Round((x.Select(y => y.ServiceTechHrs + y.ServiceEngHrs).Sum()) / totalSsrsWorkedOn, 3),
BrokenWiresFixed = brokenWiresFixed,
PercentageBrokenWires = 100 * Math.Round(brokenWiresFixed / totalSsrsWorkedOn, 4),
NPFResults = npfResults,
PercentageNPF = 100 * Math.Round(npfResults / totalSsrsWorkedOn, 4),
};
}).OrderByDescending(x => x.TotalSSRsWorkedOn)
.Dump("Summary");
return;
Sample output, with the duplicate dates evaluated (workingDatesList):
8/1/2017 12:00:00 AM
8/1/2017 12:00:00 AM
8/1/2017 12:00:00 AM
8/2/2017 12:00:00 AM
A couple of comments on the code you posted:
Since you don't ever use the day variable from the outermost loop, simply remove that loop altogether.
Why are you testing whether x.Any(...) within a loop that iterates over y? This seems fundamentally flawed.
I can't discern from your problem statement what your data structures are, nor what it is that you are actually trying to do. Your problem statement is currently worded as:
I am trying to search through a group of days, and determine if a worker has worked that day, and get a total of days worked.
It appears you are taking some input called testtech (String) and totalDaysInDateRange (List<DateTime>), then want to find all entries in some data structure x (I can't infer what this is) where String.equalsIgnoreCase(y.AssignerName, testtech) && totalDaysInDateRange.contains(y.Date). Is this interpretation correct?
If so, simply iterate over the entries in whatever your x data structure is, and run the above logic. If this doesn't solve your problem, then please give us more information on the layout of the data structure x and how information about each worker is actually associated with the other data about that worker.
BEGIN EDIT
OK, now that you have provided more information, I think you want to replace the totalDaysInDateRange.ForEach statement with the following:
x.Select(y => y.WorkedDataPointsList).ForEach((wdp) =>
{
if (testtech == wdp.AssignerName && IniDate.Date <= wdp.Date.Date
&& wdp.Date.Date <= EndDate.Date)
{
workingDatesList.Add(wdp.Date.Date);
}
});
After changing your implementation, simply delete totalDaysInDateRange. I also recommend changing the type of workingDatesList to HashSet<DateTime>, since you don't seem to care about duplicate dates. Be sure to convert workingDatesList to a list and sort it once the loop is complete if you want the dates printed in chronological order.

The specified type member 'DayOfWeek' is not supported in LINQ

I've tried using the the options from this SO question. I'm still receiving the following error though:
The specified type member 'DayOfWeek' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Question now edited to contain full code of what I'm trying to achieve. It basically required to pull the average number of SMS's sent on each day of the week.
Here is my code:
var weekDays = rad.SMSSentItems
.Where(x => x.Status == "DELIVRD")
.GroupBy(x => x.StatusDate.Value.DayOfWeek)
.Select(g => new
{
DayOfWeek = g.Key,
Count = g.Count()
})
.ToList();
int avgSMSPerMonday = 0;
int avgSMSPerTuesday = 0;
int avgSMSPerWednesday = 0;
int avgSMSPerThursday = 0;
int avgSMSPerFriday = 0;
int avgSMSPerSaturday = 0;
int avgSMSPerSunday = 0;
int totalSMSPerDay = 0;
foreach (var day in weekDays)
{
totalSMSPerDay = rad.SMSSentItems.Where(x => (DbFunctions.TruncateTime(x.StatusDate).Value.DayOfWeek == day.DayOfWeek) && (x.Status == "DELIVRD")).ToList().Count;
if (day.DayOfWeek == DayOfWeek.Monday)
avgSMSPerMonday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Tuesday)
avgSMSPerTuesday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Wednesday)
avgSMSPerWednesday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Thursday)
avgSMSPerThursday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Friday)
avgSMSPerFriday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Saturday)
avgSMSPerSaturday = totalSMSPerDay / day.Count;
else if (day.DayOfWeek == DayOfWeek.Sunday)
avgSMSPerSunday = totalSMSPerDay / day.Count;
}
Updated code using Camillo's code:
var weekDays = rad.SMSSentItems
.Where(x => x.Status == "DELIVRD")
.GroupBy(x => x.StatusDate.Value.DayOfWeek)
.Select(g => new
{
DayOfWeek = g.Key,
Count = g.Count()
})
.ToDictionary(x => x.DayOfWeek, x => x.Count);
int mondayCount = 0;
int tuesdayCount = 0;
int wednessdayCount = 0;
int thursdayCount = 0;
int fridayCount = 0;
int saturdayCount = 0;
int sundayCount = 0;
//determine average number of sms's sent per day of week
foreach (var day in weekDays)
{
int daysCount = rad.SMSSentItems
.Where(x => (x.StatusDate.Value.DayOfWeek == day.Key)
&& x.Status == "DELIVRD")
.Count();
if (day.Key == DayOfWeek.Monday)
mondayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Tuesday)
tuesdayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Wednesday)
wednessdayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Thursday)
thursdayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Friday)
fridayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Saturday)
saturdayCount = daysCount / day.Value;
else if (day.Key == DayOfWeek.Sunday)
sundayCount = daysCount / day.Value;
}
I'm still left with the initial error I get from the 1st query which is as follows:
The specified type member 'DayOfWeek' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported
You don't need to do all of that checking, you can use a Dictionary<DayOfWeek, int> instead:
var weekDays = rad.SMSSentItems
.Where(x => x.Status == "DELIVRD")
.GroupBy(x => x.StatusDate.Value.DayOfWeek)
.Select(g => new
{
DayOfWeek = g.Key,
Count = g.Count()
})
.ToDictionary(x => x.DayOfWeek);
int mondayCount = weekDays[DayOfWeek.Monday];
int tuesdayCount = weekDays[DayOfWeek.Tuesday];
//...
If you are not sure whether there'll be a value for a given day, use TryGetValue instead:
weekDays.TryGetValue(DayOfWeek.Monday, out mondayCount);
If you want the average for a given day of week, you could use something like this:
foreach (var day in weekDays)
{
int daysCount = rad.SMSSentItems
.Where(x => x.StatusDate.Value.DayOfWeek == day.DayOfWeek
&& x.Status == "DELIVRD")
.Count();
int dayAverage = day.Count / daysCount;
}

Can this data be retrieved with a single linq query?

I'm using Entity Framework. The class below represents a table from the database.
public partial class TermBucket
{
public short ID { get; set; }
public byte Period { get; set; }
public byte Min { get; set; }
public byte Max { get; set; }
}
The PK is ID and Period, so there can be multiple ID's in the table.
When querying the entity, I have at my disposal the period + time (the number associated with the period). Period is set up as an enum, so I would use it as:
Time: 3
Period: 3 (Days)
What I want to do is to find the bucket that matches by requirements and then get all entries for that bucket. Here's what I currently do:
Step 1: Get the ID
return r.Find() // this is my repository
.AsNoTracking()
.Where(x => (int)tp.Period == x.Period && tp.Time >= x.Min && tp.Time <= x.Max)
.Select(x => x.ID)
.Single();
Step 2: Get all entries for the ID, using the retrieved ID
return r.Find()
.AsNoTracking()
.Where(x => x.ID == ID );
So, there are 2 distinct queries, but is it possible to retrieve this data in one go?
Can't you just combine them?
return r.Find()
.AsNoTracking()
.Where(x => x.ID == r.Find()
.AsNoTracking()
.Where(x => (int)tp.Period == x.Period && tp.Time >= x.Min && tp.Time <= x.Max)
.Select(x => x.ID)
.Single());
You can do it using join. Example
public partial class TermBucket
{
public short ID { get; set; }
public byte Period { get; set; }
public byte Min { get; set; }
public byte Max { get; set; }
}
static void Main(string[] args)
{
List<TermBucket> l = new List<TermBucket>();
l.Add(new TermBucket() { ID = 1, Period = 3, Min = 10, Max = 14 });
l.Add(new TermBucket() { ID = 1, Period = 4, Min = 10, Max = 13 });
l.Add(new TermBucket() { ID = 1, Period = 5, Min = 100, Max = 25 });
l.Add(new TermBucket() { ID = -1, Period = 3, Min = 10, Max = 12 });
int period = 3;
int minV = 10;
int maxV = 13;
var res = from e in l
join e2 in l on e.ID equals e2.ID
where e.Period == period && minV >= e.Min && maxV <= e.Max
select e2;
foreach (var r in res)
{
Console.WriteLine(r.ID + " " + r.Period);
}
Console.ReadLine();
}
Will output
1 3
1 4
1 5
Yes, it is:
return r.Find()
.AsNoTracking()
.Where(x => x.ID == r.Find()
.AsNoTracking()
.Where(x => (int)tp.Period == x.Period && tp.Time >= x.Min && tp.Time <= x.Max)
.Select(x => x.ID)
.Single());
But I would recommend breaking it up into two queries, as you already have it, to handle the case where the first query returns no results. (As it is, currently, .Single() will throw an exception if .Select() is empty).

Joining & Transposing multiple Lists using LINQ

Hi I have the following code which returns me the right data but it seems there must be a better way to combine 3 lists, based on their common field(s) and transpose the results out into a new list of a given type using LINQ, instead of resorting to the foreach at the end. Any ideas?
public IEnumerable<StagSummaryByCflHistoricalItem> GetSummaryByCflHistorical(DateTime currentDate)
{
var allRecords =
this.preGrantSummaryHistoricalRepository
.AllWithFetch(this.preGrantSummaryHistoricalRepository.All, x => x.CaseFileLocation)
.Where(
x => x.Date >= currentDate.FirstDayOfQuarterFromDateTime()
&& x.Date <= currentDate.LastDayOfQuarterFromDateTime())
.ToList();
var summaryForQuarter =
allRecords.GroupBy(x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
x =>
new
{
CaseFileLocationId = x.Key.Id,
Description = x.Key.Name,
TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
})
.OrderBy(x => x.CaseFileLocationId)
.ToList();
var summaryForMonth =
allRecords.Where(x => x.Date >= currentDate.FirstDayOfMonthFromDateTime())
.GroupBy(x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
x =>
new
{
CaseFileLocationId = x.Key.Id,
Description = x.Key.Name,
TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
})
.OrderBy(x => x.CaseFileLocationId)
.ToList();
var summaryForWeek =
allRecords.Where(x => x.Date >= currentDate.FirstDayOfWeekFromDateTime(DayOfWeek.Monday)).GroupBy(
x => new { x.CaseFileLocation.Id, x.CaseFileLocation.Name }).Select(
x =>
new
{
CaseFileLocationId = x.Key.Id,
Description = x.Key.Name,
TotalCasesEnteredCfl = x.Sum(y => y.TotalCasesEntered),
TotalNetFeeEnteredCfl = x.Sum(y => y.TotalNetFeeEntered),
TotalCasesLeftCfl = x.Sum(y => y.TotalCasesLeft),
TotalNetFeeLeftCfl = x.Sum(y => y.TotalNetFeeLeft)
})
.OrderBy(x => x.CaseFileLocationId)
.ToList();
var finalList = summaryForQuarter
.Select(x => new StagSummaryByCflHistoricalItem()
{
CaseFileLocationId = x.CaseFileLocationId,
Description = x.Description,
QuarterTotalCasesEnteredCfl = x.TotalCasesEnteredCfl,
QuarterTotalCasesLeftCfl = x.TotalCasesLeftCfl,
QuarterTotalNetFeeEnteredCfl = x.TotalNetFeeEnteredCfl,
QuarterTotalNetFeeLeftCfl = x.TotalNetFeeLeftCfl
})
.OrderBy(x => x.CaseFileLocationId)
.ToList();
foreach (var qrt in finalList)
{
var mnthData = summaryForMonth.FirstOrDefault(x => x.CaseFileLocationId == qrt.CaseFileLocationId);
if (mnthData != null)
{
qrt.MonthTotalCasesEnteredCfl = mnthData.TotalCasesEnteredCfl;
qrt.MonthTotalCasesLeftCfl = mnthData.TotalCasesLeftCfl;
qrt.MonthTotalNetFeeEnteredCfl = mnthData.TotalNetFeeEnteredCfl;
qrt.MonthTotalNetFeeLeftCfl = mnthData.TotalNetFeeLeftCfl;
}
var weekData = summaryForWeek.FirstOrDefault(x => x.CaseFileLocationId == qrt.CaseFileLocationId);
if (weekData == null)
{
continue;
}
qrt.WeekTotalCasesEnteredCfl = weekData.TotalCasesEnteredCfl;
qrt.WeekTotalCasesLeftCfl = weekData.TotalCasesLeftCfl;
qrt.WeekTotalNetFeeEnteredCfl = weekData.TotalNetFeeEnteredCfl;
qrt.WeekTotalNetFeeLeftCfl = weekData.TotalNetFeeLeftCfl;
}
return finalList;
}
Note: I am intentionally getting the entire quarter's worth of data first as a list and then operating on it to do the month & quarter totals but this is mainly because I cannot fathom a way to get the end result from a combined LINQ IQuerable.
I am using NHibernate, LINQ method syntax, the repository pattern and SQL Server 2008
If I'm reading your code correctly, you're projecting your results to anonymous types with the same resulting members, which makes it very easy to join your results together. I did something similar recently with Union. Here's a simplified example I just wrote to demonstrate:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace ConsoleApplication1 {
public class Month {
public int MonthID { get; set; }
public string MonthName { get; set; }
public int NoDays { get; set; }
}
internal class Program {
private static void Main(string[] args) {
// Build up months
var months = new List<Month>();
for (var i = 1; i <= 12; i++) {
months.Add(new Month {
MonthID = i,
MonthName = DateTimeFormatInfo.CurrentInfo.GetMonthName(i),
NoDays = DateTime.DaysInMonth(2012, i)
});
}
var w = months.Select(m => new {
m.MonthName
});
var x = months.Select(m => new {
m.MonthName
});
var y = months.Select(m => new {
m.MonthName
});
var z = w.Union(x).Union(y);
foreach (var m in z) {
Console.WriteLine(m.MonthName);
}
Console.Read();
}
}
}
Bear in mind that "Union" (like the SQL UNION clause) will remove any duplicates from your list. If you don't want to remove duplicates (i.e. perform a "union all"), use "Concat" as follows:
var z = w.Concat(x).Concat(y);

Categories

Resources