2009-07-24 79 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) 
{ 
    // ... 
} 
相关问题