有更好的方法吗?我试图遍历partsToChange集合并构建where子句,但它将它们组合在一起而不是对它们进行ORing。我也不想在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表。
编辑: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;
答案 0 :(得分:8)
[编辑] 更好,因为partsToChange是Dictionary
:
var items = MaterialVendor.Where(m =>
m.Manufacturer.Name.Contains(partsToChange[m.Material.PartNumber])
).ToList();
答案 1 :(得分:2)
这将允许您在循环中构建Linq to sql表达式,在必要时添加带AND / OR的子句,然后在结束时执行一次。
答案 2 :(得分:0)
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到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();