2009-07-24 49 views
2

使用.Net實體框架和Linq,我有一個問題找到最佳(即最容易閱讀/理解)的方式來實現搜索實體集合是否包含任何幾個可能的值。如何確定實體集合是否包含幾個可能的值之一?

考慮一個基本的成員資格/角色實現,其中User擁有一個Roles集合。

什麼是「最好」的方式說「這個用戶有以下任何角色:角色1,角色2或角色3?」

我可以用1個角色做檢查,如:

if myUser.Roles.Contains(role1) { // do something } 

有沒有一種簡單的方法來更多的角色加入到這個檢查?

回答

2

如果角色列表在編譯時是已知的,那麼你可以做這樣的事情:

if (myUser.Roles.Count(r => r.Id == role1.Id || r.Id == role2.Id) > 0) 
{ 
    // do something 
} 

如果你想覈對角色的動態建立的列表,它變得棘手。讓我知道這是否是你需要的。

EDITED changed Any() to Count() > 0 - 我在L2E和L2SQL中誤解了這個限制。

+0

。任何()似乎並不在LINQ to是有效的實體....但是這看起來像我的:你可以用Any()方法做一個存在性檢查相結合的角色ID檢查希望完成...... – 2009-07-24 19:09:02

2

編輯:我只是跑了一些測試..有趣的是,perf對於IN與OR來說非常相似,所以除了看起來很醜的SQL之外,它們的表現幾乎相同。 我編輯了我的回覆以反映這一點。

「在」樣式查詢是不是EF(還)固有支持 我相信你想什麼來完成已經覆蓋here

你可以得到的是這樣的匹配實體:

 var roleNamesToMatch = {"Admin","Manager","Associate"}; 
     var expression = BuildOrExpression<Role, name>(r => r.Name, roleNamesToMatch); 
     var matchingRoles = context.RoleSet.Where(expression); 

基於表達式樹,EF將創建SQL它看起來是這樣的:

select r.ID,r.Name from t_Role where r.Name = 'Admin' OR r.Name = 'Manager' 
OR r.Name = 'Associate' 

代替鄰˚F什麼人通常期望

select r.ID,r.Name from t_Role where r.Name in ('Admin','Manager','Associate') 
+0

IN(...)和一系列OR語句之間沒有SQL性能差異。在查詢計劃方面,它們是相同的。 – 2009-07-25 03:31:51

+0

是的,你是對的......我編輯了我的迴應以反映這一點。 – 2009-07-25 06:12:26

0
var checkForRoles = new Role[] { Role1, Role2, Role3 }; 

if (myUser.Roles.Any(r => search.Contains(checkForRoles))) { 
    //the user is in one of the roles. 
} 
1

使用Count()會比必要更多的工作。

if(myUser.Roles.Any(role => role.Id == role1.Id || role.Id == role2.Id) 
{ 
    // ... 
} 
相關問題