Linq to Entities - SQL"IN"子句

Ste*_*McD 228 .net linq linq-to-entities in-clause

在T-SQL中,您可以进行如下查询:

SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
Run Code Online (Sandbox Code Playgroud)

你会如何在LINQ to Entities查询中复制它?它甚至可能吗?

Ben*_*ter 345

你需要根据你的想法来改变它.如果它包含当前项目的适用值,您将询问一组预定义的用户权限,而不是"在"中查找当前项目在预定义的一组适用用户权限中的用户权限.这与在.NET中的常规列表中找到项目的方式完全相同.

使用LINQ有两种方法,一种使用查询语法,另一种使用方法语法.基本上,它们是相同的,可以根据您的偏好互换使用:

查询语法:

var selected = from u in users
               where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
               select u

foreach(user u in selected)
{
    //Do your stuff on each selected user;
}
Run Code Online (Sandbox Code Playgroud)

方法语法:

var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));

foreach(user u in selected)
{
    //Do stuff on each selected user;
}
Run Code Online (Sandbox Code Playgroud)

我在这个实例中的个人偏好可能是方法语法,因为我可以通过这样的匿名调用来代替分配变量:

foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
    //Do stuff on each selected user;
}
Run Code Online (Sandbox Code Playgroud)

从语法上看,这看起来更复杂,你必须理解lambda表达式或委托的概念才能真正弄清楚发生了什么,但正如你所看到的,这会使代码压缩很多.

这一切都取决于你的编码风格和偏好 - 我的三个例子都做了同样的事情.

另一种方法甚至不使用LINQ,您可以使用相同的方法语法将"where"替换为"FindAll"并获得相同的结果,这也适用于.NET 2.0:

foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
    //Do stuff on each selected user;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果问题一直是关于Linq-to-SQL或Linq的问题,这个答案是正确的.但是,由于它具体说"Linq-to-Entities",这个答案是不正确的.Linq-to-Entities尚未支持array.Contains. (28认同)
  • @KristoferA - 对于早期版本的EF来说可能是真的,但对于EF4来说它似乎很好. (6认同)

Bal*_*dar 20

这应该足以满足你的目的.它比较两个集合并检查一个集合是否具有与另一个集合中的值匹配的值

fea_Features.Where(s => selectedFeatures.Contains(s.feaId))
Run Code Online (Sandbox Code Playgroud)


Kri*_*erA 9

如果您使用的是VS2008/.net 3.5,请参阅Alex James的提示#8:http: //blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries -使用- LINQ到entities.aspx

否则只需使用array.Contains(someEntity.Member)方法.


Pan*_*kaj 7

在这种情况下,我会选择Inner Join.如果我会使用contains,它会迭代6次,尽管事实上只有一个匹配.

var desiredNames = new[] { "Pankaj", "Garg" }; 

var people = new[]  
{  
    new { FirstName="Pankaj", Surname="Garg" },  
    new { FirstName="Marc", Surname="Gravell" },  
    new { FirstName="Jeff", Surname="Atwood" }  
}; 

var records = (from p in people join filtered in desiredNames on p.FirstName equals filtered  select p.FirstName).ToList(); 
Run Code Online (Sandbox Code Playgroud)

包含的缺点

假设我有两个列表对象.

List 1      List 2
  1           12
  2            7
  3            8
  4           98
  5            9
  6           10
  7            6
Run Code Online (Sandbox Code Playgroud)

使用Contains,它将搜索List 2中的每个List 1项,这意味着迭代将发生49次!

  • 这完全忽略了将语句转换为SQL的事实.见[这里](http://stackoverflow.com/a/31930086/861716). (4认同)

小智 5

这可能是您可以直接使用LINQ扩展方法检查in子句的可能方式

var result = _db.Companies.Where(c => _db.CurrentSessionVariableDetails.Select(s => s.CompanyId).Contains(c.Id)).ToList();
Run Code Online (Sandbox Code Playgroud)