我正在尝试对以下LINQ查询进行故障排除:
public JsonResult SearchNodesByTags(string[] tags)
{
var nodes = _DbContext.Nodes.
Where(n => n.Tags.All(t => tags.Contains(t.DisplayName)))
.Select(n => new {n.NodeNativeId, n.NodeName, n.NodeClass.ClassName})
.ToList();
return Json(nodes);
}
查询返回的是一个与标签不相关的单个节点。我想要它做的是返回具有所有标签的所有节点。
.Where(n => n.Tags.All(t => tags.Contains(t.DisplayName)))
当前的构造方式,您只会以Node
s结尾,其中的每个标签在白名单中Node.Tags
都有一个名称tags
,其中包括Node
没有标签的s。
您可能想从这里对子集使用答案:
_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
编辑
在评论中指出,使用Except可能会生成有问题的查询,因此我在想另一种选择是从数据库中获取超集,并进一步过滤应用程序内的对象:
_DbContext.Nodes
// filter nodes with any of the input tags
.Where(n => n.Tags.Any(t => tags.Contains(t.DisplayName)))
// select the information required
.Select(n => new {
n.NodeNativeId,
n.NodeName,
ClassName = n.NodeClass.ClassName,
TagNames = n.Tags.Select(t => t.DisplayName) })
// materialize super set with database
.ToList()
// filter so that only nodes with all tags remain
.Where(n => !tags.Except(n.TagNames).Any())
// produce result in anonymous class
.Select(n => new { n.NodeNativeId, n.NodeName, n.ClassName })
.ToList();
编辑2
我刚刚在这里看到了另一个可能对您有用的标签,但是它要求它Tag.DisplayName
是唯一的,因为如果您有多个具有相同标签的标签,可能会失败DisplayName
:
_dbContext.Nodes
.Where(n => n.Tags.Count(t => tags.Contains(t.DisplayName)) == tags.Count)
.Select(...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句