Can this LINQ query be simplified?
Coming from Java, I am new to C# and LINQ. There are many queries in our code base which seem to not be optimally constructed. In the following query the GroupBy lambda expression creates an anonymous data type. I can't find any examples online where GroupBy is used like this. Is there a way to simplify this query and still ret开发者_如何学运维urn the same results?
List<MachineMetrics> machines = prod.Where(p => p.TimeProduced >= start &&
p.TimeProduced <= end &&
(jobID == -1 ? true : (p.JobID == jobID && p.Job.MachineID == MachineID))).
GroupBy(x => new
{
MachineName = x.Job.Machine.MachineName,
MachineID = x.Job.MachineID,
JobName = x.Job.JobName,
JobID = x.JobID
}).
Select(item => new MachineMetrics()
{
MachineName = item.Key.MachineName,
MachineID = item.Key.MachineID,
JobName = item.Key.JobName,
JobID = item.Key.JobID
}).
ToList<MachineMetrics>();
edit: Thanks for the help. The problem was the Equals() and GetHashCode() methods were not implimented for the class. Once I added those I used the code suggested by @Ladislav Mrnka and everything worked as expected.
You are looking for this:
List<MachineMetrics> machines = prod.Where(p => p.TimeProduced >= start &&
p.TimeProduced <= end &&
(jobID == -1 ||
(p.JobID == jobID && p.Job.MachineID == MachineID))).
.Select(x => new MachineMetrics()
{
MachineName = x.Job.Machine.MachineName,
MachineID = x.Job.MachineID,
JobName = x.Job.JobName,
JobID = x.JobID
})
.Distinct()
.ToList();
Ladislav's answer is good, but just to show another alternative, preserving the GroupBy, you could reduce it to:
var machines = prod.Where(p => p.TimeProduced >= start &&
p.TimeProduced <= end &&
(jobID == -1 ? true : (p.JobID == jobID && p.Job.MachineID == MachineID))).
GroupBy(x => new MachineMetrics
{
MachineName = x.Job.Machine.MachineName,
MachineID = x.Job.MachineID,
JobName = x.Job.JobName,
JobID = x.JobID
}).
Select(item => item.Key). // 'item' is the grouping, and its 'Key' is the 'MachineMetrics' instance
ToList();
精彩评论