2011-08-10 45 views
1

来自Java,我是C#和LINQ的新手。在我们的代码库中有很多查询似乎没有被优化构建。在以下查询中,GroupBy lambda表达式创建一个匿名数据类型。我无法在网上找到任何使用GroupBy的例子。有没有办法简化这个查询,并仍然返回相同的结果?这个LINQ查询可以被简化吗?

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>(); 

编辑:感谢您的帮助。问题是Equals()和GetHashCode()方法并没有为这个类提供。一旦我添加了那些我使用@Ladislav Mrnka建议的代码,并且一切按预期工作。

+0

[下面是一个例子GroupBy使用像这样](http://stackoverflow.com/questions/847066/group-by-multiple-columns-linq)(不同的语法,但相同的结果) –

+0

但为什么赋值给变量?链接中的示例仅显示:group x by new {x.Column1,x.Column2} – Jason

+1

您只是使用该组来强制区分对吗? –

回答

4

您正在寻找这样的:

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(); 
+0

+1。请注意,原来的查询按照每个选择的'列'或属性进行分组,这与刚刚做'.Distinct()',还有'ToList ()'相同,只是更改为'ToList()',因为基本的泛型类型(MachineMetrics)已经被编译器知道了,所以不需要被指定(因为这是前面的'.Select()'的返回类型... ...我想添加这个进一步的解释,因为OP说他们是.NET和Linq的新手。 – CodingWithSpike

+0

这就是我最初的想法,但在原始代码机器中列表数为1,但是您的代码机器的列表数大于1(列表数为42)运行) – Jason

+0

@ rally25rs - 看起来不同的方法不能正常工作机器列表在每个索引处包含相同的对象 – Jason

2

拉吉斯拉夫的回答是好,但只是为了显示另一种选择,保留的GroupBy,你可以将其降低到:

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();