编写LINQ查询的方式更简单(更好)

时间:2017-02-15 20:18:58

标签: c# linq

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

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
}

有没有办法可以使用单个查询执行此操作?

我四处阅读,人们使用JOIN,但我不完全确定如何使用它。

某些表达式对于两个查询都是通用的(所选日期范围和日期ORDERBY

目前这种方式有效,但我认为有更好的方法来实现我想要实现的目标。

任何帮助将不胜感激。

编辑1:

示例SQL查询:

select * FROM [dbo].[OnDemand]
where barcode in
(
SELECT [Barcode]      
  FROM [dbo].[OnDemand]
  group by barcode
  having count(*) > 1
  )  
 and odhisdate between  '2017-01-11' and '2017-01-31' 

 and Activity like '%reprinted%'

  order by ODHisDate asc, ODHisTime asc

2 个答案:

答案 0 :(得分:4)

据我所知,不需要JOIN,因为您正在查询同一个表,而不是尝试进行递归或交叉连接查询。

为什么用相同的参数查询同一个表?您将获得List个条目,然后迭代Barcode个值,然后再次返回并使用相同的Barcode值查询同一个表。

如果你想在线迭代,语法是直截了当的,但我不确定你是否理解你在那里做什么。

dbo.OnDemand.Where(c => c.Barcode.Contains(barcode))
    .Where(c => c.ODHisDate >= start && c.ODHisDate <= end)
    .OrderBy(c => c.ODHisDate)
    .ForEach(c =>
        {
            // do stuff
        }

答案 1 :(得分:2)

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

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
}

Better Idea可以先通过常见条件进行过滤,然后按条形码进行分组,然后保留那些符合条件的组,其中条件

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