簡體   English   中英

EF LINQ-返回包含整個集合的實體

[英]EF LINQ - Return entities that contain an entire collection

我正在嘗試對以下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 ,其中Node.Tags中的每個標簽在tags白名單中都有一個名稱,其中包括沒有標簽的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包含set1每個元素,則為!set1.Except(set2).Any() == true

編輯

在評論中指出,使用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 ,但是它要求Tag.DisplayName唯一的 ,因為如果您有多個具有相同DisplayName標簽,它可能會失敗:

_dbContext.Nodes
     .Where(n => n.Tags.Count(t => tags.Contains(t.DisplayName)) == tags.Count)
     .Select(...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM