简体   繁体   English

EF LINQ-仅选择父实体

[英]EF LINQ - Select only parent Entity

I'm faced with an interesting issue. 我面临着一个有趣的问题。

I have a Node entity. 我有一个Node实体。 Nodes may or may not have Children, and also may or may not have a parent. 节点可能有或没有子级,也可能有或没有父级。

For my UI, when a user searches for a Node, I'd like to only return the Parent if the search results contain both the parent and one or many of its children (since the Parent has a Children Navigation Property). 对于我的UI,当用户搜索Node时,仅在搜索结果同时包含父级及其一个或多个子级的情况下才返回父级(因为父级具有子级导航属性)。

My result when I search for a name that contains "ParentA": 搜索包含“ ParentA”的名称时的结果:

  • ParentA ParentA
  • ParentA_ChildA ParentA_ChildA
  • ParentA_ChildB ParentA_ChildB

Desired result: 所需结果:

  • ParentA (because ParentA.Children will contain ParentA_ChildA and ParentA_ChildB ) ParentA(因为ParentA.Children将包含ParentA_ChildAParentA_ChildB

This is my current LINQ Query: 这是我当前的LINQ查询:

var results = await dbContext.Nodes.
                        Include(c => c.Parent).
                        Where(c => c.NodeName.Contains(query)).
                        OrderBy(n => n.NodeName).
                        ToPagedListAsync(page ?? 1, pageSize);

Node Entity: 节点实体:

public class Node
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long Id { get; set; }

    [Required, MaxLength(50)]
    [DisplayName("Node Name")]
    public string NodeName { get; set; }

    [ForeignKey("Parent")]
    public Nullable<long> ParentId { get; set; }
    public virtual Node Parent { get; set; }

    public virtual ICollection<Node> Children { get; set; }
}

You can use the Any method like this: c.Children.Any(x => x.NodeName.Contains(query)) 您可以使用如下所示的Any方法: c.Children.Any(x => x.NodeName.Contains(query))

var results = await dbContext.Nodes.
                        Include(c => c.Parent).
                        Where(c => c.NodeName.Contains(query)).
                        Where(c => c.Children.Any(x => x.NodeName.Contains(query))).
                        OrderBy(n => n.NodeName).
                        ToPagedListAsync(page ?? 1, pageSize);

You don't need to include parent, you can search children and return the parent. 您不需要包括父母,您可以搜索孩子并返回父母。 If you need, you can return children as well. 如果需要,您也可以返回孩子。

dbContext.Nodes.Where(
     n =>n.NodeName.Contains(query)) || n.Children.Any(
         c=>c.NodeName.Contains(query))).
                    OrderBy(n => n.NodeName).
                    ToPagedListAsync(page ?? 1, pageSize);

please try this.... 请尝试这个。

dbContext.Nodes
     .Where(c => c.NodeName.Contains(query))
     .Select(c=>GetParentOrSelf(c,query))
     .OrderBy(n => n.NodeName)
     .ToPagedListAsync(page ?? 1, pageSize);    


private Node GetParentOrSelf(Node n)
{
    if (n.Parent==null)
        return n;
    else
    {
        if (n.Parent.NodeName.Contains(query))
            return GetParentOrSelf(n.Parent,query);
        else
            return n;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM