在T-SQL中,你可以有这样的查询:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
如何复制在一个LINQ实体查询?这可能吗?
在T-SQL中,你可以有这样的查询:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
如何复制在一个LINQ实体查询?这可能吗?
当前回答
你需要彻底改变你思考问题的方式。不是执行“in”在预定义的适用用户权限集中查找当前项的用户权限,而是询问预定义的用户权限集是否包含当前项的适用值。这与您在. 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;
}
方法的语法:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
在这个例子中,我个人的偏好可能是方法语法,因为我可以在匿名调用中执行foreach,而不是分配变量:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
从语法上看,这看起来更复杂,您必须理解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;
}
其他回答
你需要彻底改变你思考问题的方式。不是执行“in”在预定义的适用用户权限集中查找当前项的用户权限,而是询问预定义的用户权限集是否包含当前项的适用值。这与您在. 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;
}
方法的语法:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
在这个例子中,我个人的偏好可能是方法语法,因为我可以在匿名调用中执行foreach,而不是分配变量:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
从语法上看,这看起来更复杂,您必须理解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;
}
我还尝试使用类似sql - in的东西-查询实体数据模型。我的方法是用一个字符串构建器来组成一个大的or表达式。这太难看了,但恐怕这是目前唯一的办法。
现在看起来是这样的:
Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
while(productIds.Count > 0)
{
sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
entities.Products.Name, productIds.Dequeue());
}
}
在这个上下文中使用GUID:正如您在上面看到的,在查询字符串片段中,GUID本身之前总是有单词“GUID”。如果不添加,ObjectQuery<T>。Where抛出以下异常:
参数类型为Edm。Guid”和 的电火花。字符串`不兼容 操作。,近似等于表达式, 第6行14列。
在MSDN论坛上找到了这个,可能会有帮助。
Matthias
... 期待下一个版本的。net和实体框架,当一切都变得更好。:)
这应该够你的目的了。它比较两个集合,并检查其中一个集合的值是否与另一个集合中的值匹配
fea_Features.Where(s => selectedFeatures.Contains(s.feaId))
严重吗?你们从没用过
where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)
在这种情况下,我将使用内连接。如果我使用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();
包含的缺点
假设我有两个列表对象。
List 1 List 2
1 12
2 7
3 8
4 98
5 9
6 10
7 6
使用Contains,它将搜索List 2中的每个List 1项,这意味着迭代将发生49次!!