2010-05-24 51 views
3

有沒有更好的方法來做到這一點?我嘗試遍歷partsToChange集合並構建where子句,但它將它們AND並在一起而不是ORing它們。我也不想明確地在partsToChange列表中的每個項目上進行平等。Linq有很長的where子句

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

這不是你where子句的大小,它是你如何使用它的重要性。 – 2010-05-24 20:26:06

+0

你有'MaterialVendor'作爲'IEnumerable '和這裏的一堂課。這是什麼? – 2010-05-24 21:50:56

+1

這是一個很短的where子句。 – Randolpho 2010-05-24 21:51:01

回答

2

查找到PredicateBuilder

這將允許你建立一個LINQ到一個循環中SQL表達式,與和/或在必要時添加的條款,然後在最後執行一次。

8

[編輯]更妙的是,因爲partsToChange是Dictionary

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

當試圖查詢數據庫時,拋出以下異常: 方法'System.String get_Item(System.String)'不支持對SQL的轉換。 – 2010-05-25 15:40:53

+0

@Jeremy:你的代碼在問題中發佈了嗎?我的[以前的編輯](http://stackoverflow.com/revisions/642074bc-df24-4d8b-ae07-8418ae7a8537/view-source)是否工作? – 2010-05-25 15:48:00

+0

您不能交叉查詢具有任何其他數據結構的L2S表,除了被轉換爲「IN(...)」的'IList.Contains(...)'以外 – cjk 2010-05-25 15:52:27

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

當試圖查詢數據庫會引發以下異常:方法'Boolean ContainsKey(System.String)'不支持對SQL的轉換。 – 2010-05-25 15:39:50