使用.Net Entity Framework和Linq,我遇到了一个问题,即找到最佳(即最容易阅读/理解)的方法来实现搜索实体集合是否包含任何可能的值。
考虑一个基本的成员资格/角色实现,其中User有一个Roles集合。
说“此用户是否具有以下任何角色:role1,role2或role3?”的“最佳”方式是什么?
我可以用1个角色来检查,如:
if myUser.Roles.Contains(role1) { // do something }
是否有一种简单的方法可以为此检查添加更多角色?
答案 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”样式查询本身并不支持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.
}