EF 相交语法
EF Intersect Syntax
A UI 允许用户 select 一个或多个标签。我想 select 所有具有用户输入的所有标签的节点, 而不是 只是一个标签。
public JsonResult SearchNodesByTags(string[] tags)
{
var dbTags = _DbContext.Tags.Where(t => tags.Contains(t.DisplayName)).ToList();
var nodes = _DbContext.Nodes.Where(n => n.Tags.Intersect(dbTags).Any());
// Error about intersection with non primitive
return Json(nodes);
}
您可以在一条语句中完成此操作:
var nodes = _DbContext.Nodes
.Where(n => n.Tags.All(t => tags.Contains(t.DisplayName)));
您的陈述不正确,因为 dbTags
是包含 Tag
个对象的本地列表。当您在 LINQ-to-Entities 表达式中使用此列表时,无法将这些对象转换为 SQL 变量。这只有使用原始值才有可能。
var nodes = _DbContext.Nodes.Where(n => n.Tags.Intersect(dbTags).Any());
首先,你不能在 Linq-to-Entities 表达式中使用对象,所以你必须使用类似这样的东西来比较:
n.Tags.Select(t => t.DisplayName).Intersect(tags)
其次,Intersect
将为您提供两个给定集合中的项目集,因此您最终会得到所有 Node
具有 any 个标签,而不是所有具有 all 个标签的节点。
如果您想要包含 tags
中每个 Tag
的所有 Node
,您可能希望在子集上使用 here 的答案:
_DbContext.Nodes
.Where(n => !tags.Except(n.Tags.Select(t => t.DisplayName)).Any())
.Select(...
set1.Except(set2)
包含 set1
中不在 set2
中的元素
!set1.Except(set2).Any() == true
如果 set2
包含 set1
的每个元素
A UI 允许用户 select 一个或多个标签。我想 select 所有具有用户输入的所有标签的节点, 而不是 只是一个标签。
public JsonResult SearchNodesByTags(string[] tags)
{
var dbTags = _DbContext.Tags.Where(t => tags.Contains(t.DisplayName)).ToList();
var nodes = _DbContext.Nodes.Where(n => n.Tags.Intersect(dbTags).Any());
// Error about intersection with non primitive
return Json(nodes);
}
您可以在一条语句中完成此操作:
var nodes = _DbContext.Nodes
.Where(n => n.Tags.All(t => tags.Contains(t.DisplayName)));
您的陈述不正确,因为 dbTags
是包含 Tag
个对象的本地列表。当您在 LINQ-to-Entities 表达式中使用此列表时,无法将这些对象转换为 SQL 变量。这只有使用原始值才有可能。
var nodes = _DbContext.Nodes.Where(n => n.Tags.Intersect(dbTags).Any());
首先,你不能在 Linq-to-Entities 表达式中使用对象,所以你必须使用类似这样的东西来比较:
n.Tags.Select(t => t.DisplayName).Intersect(tags)
其次,Intersect
将为您提供两个给定集合中的项目集,因此您最终会得到所有 Node
具有 any 个标签,而不是所有具有 all 个标签的节点。
如果您想要包含 tags
中每个 Tag
的所有 Node
,您可能希望在子集上使用 here 的答案:
_DbContext.Nodes
.Where(n => !tags.Except(n.Tags.Select(t => t.DisplayName)).Any())
.Select(...
set1.Except(set2)
包含set1
中不在set2
中的元素
!set1.Except(set2).Any() == true
如果set2
包含set1
的每个元素