在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实体查询?这可能吗?
当前回答
在这种情况下,我将使用内连接。如果我使用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次!!
其他回答
在这种情况下,我将使用内连接。如果我使用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次!!
这可能是直接使用LINQ扩展方法检查in子句的可能方式
var result = _db.Companies.Where(c => _db.CurrentSessionVariableDetails.Select(s => s.CompanyId).Contains(c.Id)).ToList();
真实的例子:
var trackList = Model.TrackingHistory.GroupBy(x => x.ShipmentStatusId).Select(x => x.Last()).Reverse();
List<int> done_step1 = new List<int>() {2,3,4,5,6,7,8,9,10,11,14,18,21,22,23,24,25,26 };
bool isExists = trackList.Where(x => done_step1.Contains(x.ShipmentStatusId.Value)).FirstOrDefault() != null;
我还尝试使用类似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和实体框架,当一切都变得更好。:)
这不是确切的IN操作符,但它可能帮助您获得预期的结果,并且可能是一种更通用的方法(因为它允许比较两个集合):INTERSECT
下面是一个工作示例
var selected =
users.Where(u =>
new[] { "Admin", "User", "Limited" }.Intersect(new[] {u.User_Rights}).Any()
);
OR
var selected =
users.Where(u =>
new[] {u.User_Rights}.Intersect(new[] { "Admin", "User", "Limited" }).Any()
);
我想应该对性能进行基准测试(针对目前接受的答案),以充分验证这个解决方案……
编辑:
正如Gert Arnold所要求的例子(EF 6): 这段代码给出了名字和/或姓氏匹配“John”或“Doe”的任何用户:
// GET: webUsers
public async Task<ActionResult> Index()
{
var searchedNames = new[] { "John", "Doe" };
return
View(
await db
.webUsers
.Where(u => new[] { u.firstName, u.lastName }.Intersect(searchedNames).Any())
.ToListAsync()
);
//return View(await db.webUsers.ToListAsync());
}