2009-04-08 99 views
3

單個和多個列表的LINQ to SQL:對列表,數組和對象列表

考慮以下列表的高級查詢:

List<Int32> appleIdentities = new List<int>(new[] { 1, 2, 3 }); 
List<Int32> chocolateIdentities = new List<int>(new[] { 2, 3, 4 }); 
List<Int32> icecreamIdentities = new List<int>(new[] { 11, 14, 15, 16 }); 

使用LINQ to SQL;是否可以寫出一條語句翻譯爲:

SELECT 
    DesertsID, 
    DesertsName 
FROM 
    Deserts 
WHERE 
    Deserts.AppleIdentity IN (1, 2, 3) AND 
    Deserts.ChocolateIdentity IN (2, 3, 4) AND 
    Deserts.IcecreamIdentity IN (11, 14, 15m 16) 

如果是;代碼看起來如果我想查詢我的沙漠數據庫,只需要對appleIdentities列表進行查詢?



陣列

考慮以下的數組:

Int32[] appleIdentities = new[] {1, 2, 3, 4}; 
String[] chocolateNames = new[] {"Light", "Dark"}; 

使用LINQ to SQL;是否可以寫出一條語句翻譯爲:

SELECT 
    DesertsID, 
    DesertsName 
FROM 
    Deserts 
WHERE 
    Deserts.AppleIdentity IN (1, 2, 3) AND 
    Deserts.ChocolateName IN ('Light', 'Dark') 

如果是;代碼看起來如果我想查詢我的沙漠數據庫而不是appleIdentities陣列?對象



列表

考慮以下幾點:

public class Identities 
{ 
    public Int32 appleIdentity { get; set; } 
    public String chokolateName { get; set; } 
} 

List<Identities> identities = new List<Identities>(new[] { 
    new Identities { appleIdentity = 1, chokolateName = "Light" }, 
    new Identities { appleIdentity = 2, chokolateName = "Dark" }, 
}); 

使用LINQ to SQL;是否可以寫出一條語句翻譯爲:

SELECT 
    DesertsID, 
    DesertsName 
FROM 
    Deserts 
WHERE 
    Deserts.AppleIdentity IN (1, 2) AND 
    Deserts.ChocolateName IN ('Light', 'Dark') 

如果是;如果我想查詢我的沙漠數據庫和Identities對象列表上的appleIdentity-properties,代碼將如何查看?


這是分叉的LINQ to SQL query against a list of entities

回答

2

當然 - 只需使用Contains - 使用的Northwind爲例:

var qry = from cust in ctx.Customers 
      where custIds.Contains(cust.CustomerID) 
      && regions.Contains(cust.Region) 
      select cust; // or your custom projection 
+1

這很有趣,但我每次看這件事。我總是嘗試使用.Any()... – mcfea 2014-06-18 23:54:37

2

好了,你可以試試:

​​

我相信,沒關係,儘管當列表獲得足夠大的IIRC它會失敗。列表和數組應該可以。

雖然我不確定你的第三個查詢 - 我想你需要每個單獨的Contains調用的列表。

3

如何將代碼看起來,如果我想 查詢我的沙漠的數據庫免受 只是appleIdentities列表?

你可以在多個語句中編寫一個linq查詢,就像這樣,並在運行時選擇你想要在where子句中使用哪個過濾器。

var query = db.Desserts; 
if (filterbyAppleIdentity) 
    query = query.Where(q => appleIdentities.Contains(q.DesertsID)); 
if (filterbyChocolateIdentities) 
    query = query.Where(q => chocolateIdentities.Contains(q.DesertsID)); 
if (filterbicecreamIdentities) 
    query = query.Where(q => icecreamIdentities.Contains(q.DesertsID)); 

var deserts = query.ToList(); 

,你也可以寫一個擴展方法來做到這一點沒有if語句:(編輯固定錯字,返回類型應該是IQueriable

public static class LinqExtensions { 
    public IQueriable<T> CondWhere<T>(this IQueriable<T> query, bool condition, Expression<Func<T,bool>> predicate) { 
    if (condition) 
     return query.Where(predicate); 
    else 
     return query; 
    } 
} 

,寫你的LINQ查詢是這樣的:

var deserts = db.Desserts; 
     .CondWhere(filterbyAppleIdentity, q => appleIdentities.Contains(q.DesertsID)); 
     .CondWhere(filterbyChocolateIdentities, q => chocolateIdentities.Contains(q.DesertsID)); 
     .CondWhere(filterbicecreamIdentities, q => icecreamIdentities.Contains(q.DesertsID)).ToList(); 

另一種方法是將ID列表聯合:

var deserts = db.Deserts 
     .Where(d => appleIdentities.Union(chocolateIdentities).Union(icecreamIdentities).Contains(d.DesertsID); 

對於對象的列表,你可以使用。選擇擴展方法到項目列表成int或字符串IEnumerable和您可以使用包含在以同樣的方式查詢:

var deserts = db.Deserts 
    .Where(d => 
     identities.Select(i => i.appleIdentity).Contains(d => d.DesertID) && 
     identities.Select(i => i.chokolateName).Contains(d => d.DesertsName) 
    ) 
+0

爲什麼downvote?你能解釋我的答案有什麼問題嗎? – 2009-04-08 20:17:27

2

正如其他人所說,LinqToSql將翻譯ContainsIN

有一些注意事項:

  • 這個翻譯工程List<T>.Contains(),但IList<T>.Contains()不起作用。它是否適用於數組?我不知道。
  • 此翻譯將盡可能多地翻譯儘可能多的元素 - 每個元素都變成一個sql參數。 SQL Server 2008有大約2000個參數限制,會向您發送SQL例外,如果您嘗試使用過大的集合。
  • 將此翻譯應用於字符串集合時,將生成參數nvarchar參數。如果目標列是varchar並且您想要使用此列的索引,則這可能是一個嚴重問題。 Sql Server將轉換成索引,而不是參數......它涉及讀取和轉換整個索引中的每個字符串。

下面是一些代碼爲你對象列表問題:

List<int> someIDs = identities 
    .Select(x => x.appleIdentity).ToList(); 
List<string> someStrings = identities 
    .Select(x => x.chokolateName).ToList(); 

var query = db.Desserts.Where(d => 
    someIDs.Contains(d.AppleIdentity) && 
    someStrings.Contains(d.ChocolateName) 
)