使用导航深度加载实体2级 [英] Using navigation to load entity 2 level deep

查看:32
本文介绍了使用导航深度加载实体2级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我上课

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>

Using navigation properties i could load List<Level2> like this

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

但是我如何加载 Level3 及其与 Level2 链接的属性?

but how do I load Level3 and its properties that is linked with Level2?

PS:无法进行延迟加载.这是 Getsingle 函数

PS: Lazy loading is not possible. This is the Getsingle function

    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;
    }

推荐答案

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

Your GetSingle method should be this way:

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方法:

I don't know what are you doing in the GetFilteredSet method, but I guess you can reorganize the code I show above at your convenience. The key to include more than one level of nav. properties in EF is use the Include method. When you use this method you are going to load the nav. properties as part of your query (check eager loading section in this link). Now, there are two Include methods :

此方法需要传递导航的路径.您想要以字符串形式加载的属性,例如,在您的情况下,将是:

Whit this method you need to pass the path of the nav. properties you want to load as an string, for example, in your case, it would be:

context.Set<Level1>.Include("Level2List.Level3");

  • DbExtensions.Include扩展方法

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

    This is the method that I use in my above code where you can specify the related objects to include using a lambda expression. IMHO this is the best variant because is strongly typed, and if you change some of the nav. properties name in your entities, you are also going to receive a compilation error(s). In the link I share above, you can see all the patterns you can use to include different levels of nav. properties.

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

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

    Returning to the initial problem, now you can use your GetSingle method to include more than one level this way:

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

    这篇关于使用导航深度加载实体2级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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