EF LINQ - 返回包含整个集合的实体

时间:2015-06-19 22:16:58

标签: c# asp.net entity-framework linq-to-entities

我正在尝试解决以下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);
}

查询返回与标记无关的单个节点。我想要它做的是返回任何包含所有标签的节点。

1 个答案:

答案 0 :(得分:2)

  .Where(n => n.Tags.All(t => tags.Contains(t.DisplayName)))

目前的构建方式,您最终只会得到Node,其中 Node.Tags中的每个标记都在{{1}中有一个名称白名单,其中包含没有标记的tags

您可能希望在子集上使用here的答案:

Node
  • _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

修改

评论中指出,使用Except可能会产生有问题的查询,因此我认为另一种选择是从数据库中获取超集,并进一步过滤应用程序中的对象:

set1

修改2

我刚刚看到另一个可能适合您的here,但它要求_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(); 唯一 ,因为它可能会失败您有多个具有相同Tag.DisplayName的标签:

DisplayName