如何确定实体集合是否包含多个可能值中的一个?

时间:2009-07-24 18:54:34

标签: c# linq entity-framework

使用.Net Entity Framework和Linq,我遇到了一个问题,即找到最佳(即最容易阅读/理解)的方法来实现搜索实体集合是否包含任何可能的值。

考虑一个基本的成员资格/角色实现,其中User有一个Roles集合。

说“此用户是否具有以下任何角色:role1,role2或role3?”的“最佳”方式是什么?

我可以用1个角色来检查,如:

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

是否有一种简单的方法可以为此检查添加更多角色?

4 个答案:

答案 0 :(得分:2)

如果在编译时知道角色列表,那么你可以这样做:

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

如果要检查动态构建的角色列表,则会变得更加棘手。如果这是你需要的,请告诉我。

已编辑已将Any()更改为Count() > 0 - 我在L2E与L2SQL中错误地记录了此限制。

答案 1 :(得分:2)

编辑:我刚刚运行了一些测试。有趣的是,对于IN与OR,perf非常相同,所以除了看起来很丑的SQL之外,它们的表现几乎相同。 我编辑了我的回复以反映这一点。

“IN”样式查询本身并不支持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'

而不是人们通常期望的

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

答案 2 :(得分:1)

使用Count()将完成超出必要的工作。您可以将角色ID检查与Any()方法结合起来进行存在检查:

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

答案 3 :(得分:0)

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

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