带有长 where 子句的 Linq

发布于 2024-09-02 08:48:50 字数 1343 浏览 9 评论 0原文

有更好的方法吗?我尝试循环 partsToChange 集合并构建 where 子句,但它将它们组合在一起,而不是对它们进行 OR 运算。我也不想明确地对 partsToChange 列表中的每个项目进行相等。

var partsToChange = new Dictionary<string, string> {
    {"0039", "Vendor A"},
    {"0051", "Vendor B"},
    {"0061", "Vendor C"},
    {"0080", "Vendor D"},
    {"0081", "Vendor D"},        
    {"0086", "Vendor D"},
    {"0089", "Vendor E"},
    {"0091", "Vendor F"},
    {"0163", "Vendor E"},
    {"0426", "Vendor B"},
    {"1197", "Vendor B"}
};

var items = new List<MaterialVendor>();
foreach (var x in partsToChange)
{
    var newItems = (
    from m in MaterialVendor 
    where 
        m.Material.PartNumber == x.Key 
        && m.Manufacturer.Name.Contains(x.Value)
    select m
    ).ToList();
    items.AddRange(newItems);
}

附加信息:我正在 LINQPad 中工作,这是一个 LinqToSql 查询。这里MaterialVendor既是一个类,也是一个DataContext Table。

编辑:LinqToSql 详细信息。

这似乎是我发现的可读性和降低复杂性的最佳方法。它还具有无需显式定义集合类型的额外好处。这意味着我可以改变匿名类型返回的内容。

var predicate = PredicateBuilder.False<MaterialVendor>();

foreach (var x in partsToChange)
{
    var item = x;
    predicate = predicate.Or (m =>
        m.Material.PartNumber == item.Key 
        && m.Manufacturer.Name.Contains(item.Value));
}

var items = from m in MaterialVendor.Where(predicate)
    select m;

Is there a better way to do this? I tried to loop over the partsToChange collection and build up the where clause, but it ANDs them together instead of ORing them. I also don't really want to explicitly do the equality on each item in the partsToChange list.

var partsToChange = new Dictionary<string, string> {
    {"0039", "Vendor A"},
    {"0051", "Vendor B"},
    {"0061", "Vendor C"},
    {"0080", "Vendor D"},
    {"0081", "Vendor D"},        
    {"0086", "Vendor D"},
    {"0089", "Vendor E"},
    {"0091", "Vendor F"},
    {"0163", "Vendor E"},
    {"0426", "Vendor B"},
    {"1197", "Vendor B"}
};

var items = new List<MaterialVendor>();
foreach (var x in partsToChange)
{
    var newItems = (
    from m in MaterialVendor 
    where 
        m.Material.PartNumber == x.Key 
        && m.Manufacturer.Name.Contains(x.Value)
    select m
    ).ToList();
    items.AddRange(newItems);
}

Additional info: I am working in LINQPad and this is a LinqToSql query. Here MaterialVendor is both a class and a DataContext Table.

Edit: LinqToSql details.

This seems to be the best method that I have found for both readability and reducing the complexity. It also has the added benefit of not having the collection type defined explicitly. That means I can vary what comes back with an anonymous type.

var predicate = PredicateBuilder.False<MaterialVendor>();

foreach (var x in partsToChange)
{
    var item = x;
    predicate = predicate.Or (m =>
        m.Material.PartNumber == item.Key 
        && m.Manufacturer.Name.Contains(item.Value));
}

var items = from m in MaterialVendor.Where(predicate)
    select m;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

莫言歌 2024-09-09 08:48:50

[编辑] 更好,因为 partsToChange 是一个 Dictionary

var items = MaterialVendor.Where(m =>
                m.Manufacturer.Name.Contains(partsToChange[m.Material.PartNumber])
            ).ToList();

[Edit] Even better, since partsToChange is a Dictionary:

var items = MaterialVendor.Where(m =>
                m.Manufacturer.Name.Contains(partsToChange[m.Material.PartNumber])
            ).ToList();
下雨或天晴 2024-09-09 08:48:50

查看 PredicateBuilder

这将允许您在循环内构建 Linq to sql 表达式,必要时用 AND / OR 添加子句,然后在最后执行一次。

Look into PredicateBuilder

This will allow you to build a Linq to sql expression within a loop, adding the clauses with AND / OR where necessary, then execute it once at the end.

牵你手 2024-09-09 08:48:50

where 子句的大小并不重要。 循环内的查询是降低可维护性和性能的部分。

List<MaterialVendor> items = 
(
  from z in MaterialVendor
  let partKey = z.Material.PartNumber
  where partsToChange.ContainsKey(partKey)
  let partValue = partsToChange[partKey]
  where z.Manufacturer.Name.Contains(partValue)
  select z
).ToList();

现在我们知道涉及 linq to sql...这是一个混合模式查询。

List<string> keys = partsToChange.Keys.ToList();

List<MaterialVendor> items =  
( 
  from z in MaterialVendor 
  let partKey = z.Material.PartNumber 
  where keys.Contains(partKey)
  select new {MatVendor = z, Name = z.Manufacturer.Name, Key = partKey}
).AsEnumerable()
.Where(x => x.Name.Contains(partsToChange[x.partKey]))
.Select(x => x.MatVendor)
.ToList(); 

The where clause size doesn't really matter. The querying within a loop is the part that drives maintainability and performance down.

List<MaterialVendor> items = 
(
  from z in MaterialVendor
  let partKey = z.Material.PartNumber
  where partsToChange.ContainsKey(partKey)
  let partValue = partsToChange[partKey]
  where z.Manufacturer.Name.Contains(partValue)
  select z
).ToList();

Now that we know that linq to sql is involved... here's a mixed mode query.

List<string> keys = partsToChange.Keys.ToList();

List<MaterialVendor> items =  
( 
  from z in MaterialVendor 
  let partKey = z.Material.PartNumber 
  where keys.Contains(partKey)
  select new {MatVendor = z, Name = z.Manufacturer.Name, Key = partKey}
).AsEnumerable()
.Where(x => x.Name.Contains(partsToChange[x.partKey]))
.Select(x => x.MatVendor)
.ToList(); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文