使用导航加载实体2级深度

本文关键字:2级 深度 实体 加载 导航 | 更新日期: 2023-09-27 18:11:23

我有一个class

public class Level1
{
   public int Id {get; set;}
   public virtual List<Level2> Level2List {get; set;}
}
public class Level2
{
   public int Id {get; set;}
   public int Level3Id {get; set;}
   public virtual Level3 Level3 {get; set;}
}
public class Level3
{
   public int Id {get; set;}
   public string Name {get; set;}
}

使用导航属性,我可以像这样加载List<Level2>

var myList = _myLevel1Repository.GetSingle(x=>x.Id == Level1Id, x=>x.Level2List);

但是我如何加载Level3及其与Level2相关联的属性?

PS:延迟加载是不可能的。这是Getsingle函数

    public T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navProps)
    {
        T item = null;
        using (var context = new MyDbContext())
            item = GetFilteredSet(context, navProps).AsNoTracking().FirstOrDefault(where);
        return item;
    }

使用导航加载实体2级深度

你的GetSingle方法应该是这样的:

public T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navProps)
{
    T item = null;
    using (var context = new MyDbContext())
    {
        IQueryable<T> query = context.Set<T>();
        //Include the navigations properties as part of the query
        if (navProps!= null)
        {
            query = navProps.Aggregate(query, (current, include) => current.Include(include));
        }
        item = query.Where(where).FirstOrDefault();
    }
    return item;
}

我不知道你在GetFilteredSet方法中做了什么,但我猜你可以在方便的时候重组我上面展示的代码。关键是要包含多个级别的导航。EF中的属性使用Include方法。当你使用这个方法时,你将会加载导航。属性作为查询的一部分(请查看此链接中的即时加载部分)。现在,有两个Include方法:

  • DbQuery。包括方法

    使用此方法时,您需要传递导航的路径。您希望作为字符串加载的属性,例如,在您的示例中,它将是:

    context.Set<Level1>.Include("Level2List.Level3");
    
  • DbExtensions。包含扩展方法

    这是我在上面的代码中使用的方法,您可以使用lambda表达式指定要包含的相关对象。恕我直言,这是最好的变体,因为它是强类型的,如果你改变一些导航。属性名称在您的实体中,您还将收到一个编译错误。在我上面分享的链接中,你可以看到所有你可以用来包含不同级别导航的模式。属性。

    context.Set<Level1>.Include(l1=>l1.Level2List.Select(l2=>l2.Level3));
    

回到最初的问题,现在您可以使用GetSingle方法以这种方式包含多个级别:

var entity= _myLevel1Repository.GetSingle(x=>x.Id == Level1Id, x=>x.Level2List.Select(l2=>l2.Level3));

如何使用include?

 var mylevel1s = _db.Level1(x=>x.Id == Level1Id).Include(x=> x.Level2List.Select(a=>a.Level3));