C# 编写LINQ查询的更简单(更好)的方法

C# 编写LINQ查询的更简单(更好)的方法,c#,linq,C#,Linq,我有两个LINQ查询,我使用第一个LINQ查询的结果,使用foreach循环迭代找到的每个元素,并在第二个LINQ查询中使用它 var entries = dbo.OnDemand.Where(c => c.LOTNO == LotNo).Where(c => c.ODHisDate >= start && c.ODHisDate <= end).Where(c => c.Activity.Contains(reprinted)).OrderBy(c

我有两个
LINQ
查询,我使用第一个
LINQ
查询的结果,使用foreach循环迭代找到的每个元素,并在第二个
LINQ
查询中使用它

var entries = dbo.OnDemand.Where(c => c.LOTNO == LotNo).Where(c => c.ODHisDate >= start && c.ODHisDate <= end).Where(c => c.Activity.Contains(reprinted)).OrderBy(c => c.ODHisDate);

foreach (var X in entries)
{  
    Barcodes.Add(X.Barcode);    // Barcodes is a List<string>
}

foreach (string barcode in Barcodes)
{
    var entries2 = dbo.OnDemand.Where(c => c.Barcode.Contains(barcode)).Where(c => c.ODHisDate >= start && c.ODHisDate <= end).OrderBy(c => c.ODHisDate);

    // Do stuff with entries2
}

据我所知,没有必要使用
联接
,因为您正在查询同一个表,并且没有尝试执行递归或交叉联接查询

为什么要用相同的参数查询相同的表?返回条目的
列表
,然后遍历
条形码
值,然后再次返回并使用相同的
条形码
值查询相同的表

如果您想在线进行迭代,语法是直截了当的,但是我不确定您是否理解您在那里做的事情

dbo.OnDemand.Where(c => c.Barcode.Contains(barcode))
    .Where(c => c.ODHisDate >= start && c.ODHisDate <= end)
    .OrderBy(c => c.ODHisDate)
    .ForEach(c =>
        {
            // do stuff
        }
dbo.OnDemand.Where(c=>c.Barcode.Contains(Barcode))
。其中(c=>c.ODHisDate>=开始和&c.ODHisDate c.ODHisDate)
.ForEach(c=>
{
//做事
}

我猜您这样做是因为存在具有相同条形码的元素。解决方案可能是:

var entries = dbo.OnDemand.Where(c => c.LOTNO == LotNo 
                                   && c.ODHisDate >= start && c.ODHisDate <= end 
                                   && c.Activity.Contains(reprinted))
                          .Select(c => c.Barcode);//Don't need to orderby here

// You will get a IEnumerable<List<OnDemand>> as result of this query
var entries2 =entries.Select(barcode =>  dbo.OnDemand.Where(c => c.Barcode.Contains(barcode) 
                                                              && c.ODHisDate >= start && c.ODHisDate <= end)
                                                     .OrderBy(c => c.ODHisDate)
                                                     .ToList());

foreach (var list in entries2)
{
 // do stuff
}
var entries=dbo.OnDemand.Where(c=>c.LOTNO==LOTNO
&&c.ODHisDate>=start&&c.ODHisDate c.Barcode);//不需要在此处订购
//您将得到一个IEnumerable作为此查询的结果
var entries2=entries.Select(条形码=>dbo.OnDemand.Where(c=>c.barcode.Contains(条形码)
&&c.ODHisDate>=开始和&c.ODHisDate c.ODHisDate)
.ToList());
foreach(条目2中的var列表)
{
//做事
}
更好的方法是先按通用条件过滤,然后按条形码分组,然后保留那些具有满足第二个条件的元素的组

var entries = dbo.OnDemand.Where(c.ODHisDate >= start && c.ODHisDate <= end)
                          .GroupBy(c=>c.BarCode)
                          .Where(g=>g.Any(c=>c.LOTNO == LotNo && c.Activity.Contains(reprinted) ))
                          .Select(g=>g.OrderBy(c => c.ODHisDate).ToList()); 
var entries=dbo.OnDemand.Where(c.ODHisDate>=start&&c.ODHisDate c.BarCode)
其中(g=>g.Any(c=>c.LOTNO==LOTNO&&c.Activity.Contains(重印)))
.Select(g=>g.OrderBy(c=>c.ODHisDate.ToList());
更新
var entries=dbo.OnDemand.Where(c.ODHisDate>=start&&c.ODHisDate c.BarCode)
.Where(g=>g.Count()>1)
.选择(g=>g.OrderBy(c=>c.ODHisDate));

您能解释一下这里的逻辑吗?模型会有帮助。@Octaviccl-第一次查询时,我得到了一个符合条件的条形码列表。在第二次查询中,我得到了基于每个条形码的条目。您应该使您的代码尽可能容易调试。有一个长的linq语句会使调试变得非常困难,因为当您如果这些语句中有一个错误,堆栈跟踪仅显示这些linq链的第一行(即,即使问题发生在第4行,它也会显示第1行)。我建议在select语句中进行这些条件检查,并将该select语句作为一个单独的函数,或者一个一个地进行检查。您可以对您的答案进行更多的解释吗?在运行第一个查询之前,我不会知道条形码。因此,我认为我不能使用
。Where(c=>c.Barcode.Contains(Barcode))
但我会试试看,你有SQL查询示例吗?你要做的是获取所有条形码,然后遍历刚获取的条形码并再次查询同一个表?你为什么要这样做?在这一点上,条形码甚至对你没有任何影响:你得到的是什么,你再次查询……使用相同的参数。我只需要你的q我已经添加了一个用于测试的示例SQL查询。是的,您是对的,有一些元素具有相同的条形码,我试图在找到重新打印的条形码时显示信息。我还在第一个查询中删除了
orderby
。您编辑的查询不同,简化了问题在SQL server management studio中使用该查询进行测试,但我不知道如何用C编写该查询#不,我还没有尝试过。我会在有机会时尝试,并告诉您结果。我修改了您的更新查询,现在它可以工作了。感谢您的帮助。感谢@bc004346提供建议的答案
var entries = dbo.OnDemand.Where(c.ODHisDate >= start && c.ODHisDate <= end)
                          .GroupBy(c=>c.BarCode)
                          .Where(g=>g.Any(c=>c.LOTNO == LotNo && c.Activity.Contains(reprinted) ))
                          .Select(g=>g.OrderBy(c => c.ODHisDate).ToList()); 
var entries = dbo.OnDemand.Where(c.ODHisDate >= start && c.ODHisDate <= end && c.Activity.Contains(reprinted))
                          .GroupBy(c=>c.BarCode)
                          .Where(g=>g.Count()>1)
                          .Select(g=>g.OrderBy(c => c.ODHisDate));