实体框架-检查是否有孙记录 [英] Entity Framework - check whether has grandchild records

查看:53
本文介绍了实体框架-检查是否有孙记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP Net Core 2.0和实体框架来访问MySQL数据库.我的模型结构看起来像

I am using asp net core 2.0 and entity framework to access a MySQL database. My model structure looks like

public class Parent 
{
   [Key]
   public int Id { get; set; }
   public virtual ICollection<Child> Child { get; set; }
   [NotMapped]
   public virtual bool HasGrandchild  { get; set; }
}

public class Child
{
   [Key]
   public int Id { get; set; }
   public int ParentId { get; set; }
   public virtual ICollection<Grandchild> Grandchild { get; set; }
}

public class Grandchild
{
   [Key]
   public int Id { get; set; }
   public int ChildId { get; set; }
}

我想检查在 Parent 类中是否有任何孙子记录.我知道我可以使用 Include ThenInclude 来检索子代和孙代.但是,孙子确实很大.我不想退还他们.或者,我可以使用 for 循环来计数孙子代号.例如,

I want to check whether there are any records of grandchild in the class Parent. I know I can use Include and ThenInclude to retrieve the child and grandchild. However, the Grandchild is really big. I don't want to return them. Alternatively, I could use for loop to count the number Grandchild. For example,

List<Parent> p_list = _context.Parent.ToList();
foreach(Parent p in p_list) 
{
    List<Child> c_list = _context.Child
        .Where(c => c.ParentId == p.Id)
        .ToList();
    int NumberOfGrandchild = 0;
    foreach (Child c in c_list) 
    {
        List<Grandchild> gc_list = _context.Grandchild
           .Where(gc =>gc.ChildId == c.Id)
           .ToList();
        NumberOfGrandchild  += gc_list.Count();
    }
    p.HasGrandchild = false;
    if (NumberOfGrandchild > 0) {
        p.HasGrandchild = true;
    }
}

此方法的性能非常慢,尤其是对于大表.

The performance of this method is very slow, especially for the big table.

有没有更好的方法来检查是否有孙记录.

Is there any better method to check whether there are any grandchild records.

推荐答案

var parents = _context.Parents
                      .Where(p => p.Children.SelectMany(c => c.Grandchildren).Any());

应该为您提供所需的内容.您希望尽可能避免使用 Include ,因为它将整个表的列添加到查询中.(至少它是对< = EF5所做的.)

This should give you what you're looking for. You want to avoid Include as much as possible, because it adds the entire table's columns to the query. (At least it did with <= EF5.)

这里发生的是您正在生成子查询,其中最低的子查询将为 parent 获取所有的 Children ,并查看是否有任何 Child 有任何孙子.

What's happening here is that you're generating subqueries, the lowest of which will get all Children for the parent, and see if any Child has any Grandchild.

如果您想确定 Parent 是否有任何 Grandhildren ,则可以将 Where 子句的该部分移开,或者只具有 true 在一个匿名对象中.

If you want to determine if a Parent has any Grandhildren then you can either move that portion of the Where clause, or just have true in an anonymous object.

var parents = _context.Parents
                      .Select(p => new { // Can be other DTO if you have one
                          Parent = p,
                          HasGrandchildren = p.Children
                                              .SelectMany(c => c.Grandchildren)
                                              .Any()
                      });

var parents = _context.Parents
                      .Where(p => p.Children.SelectMany(c => c.Grandchildren).Any())
                      .Select(p => new {
                          Parent = p,
                          HasGrandchildren = true
                      });

第二个可能性能更高,因为它能够在单个查询中执行该操作.第一个可能可能会使查询的速度稍慢一些,但也可以使您获得所有信息.

The second one probably be a little more performant because it would be able to perform that within a single query. The first might be slightly slower of a query, but it would also allow you to get everything.

如果要在有子孙的孩子和没有子孙的孩子之间进行划分,还可以通过 GroupBy 进行其他操作.

There are also other ways you could do that with a GroupBy if you want to split them between those that do have grandchildren, and those that don't.

这篇关于实体框架-检查是否有孙记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆