【问题标题】:EntityFramework Eager Load all Navigation PropertiesEntityFramework Eager 加载所有导航属性
【发布时间】:2013-09-14 18:07:36
【问题描述】:

我将存储库模式与 DI 和 IoC 一起使用。

我在我的存储库中创建了一个函数:

T EagerGetById<T>(Guid id, string include) where T : class
{
    return _dbContext.Set<T>().Include(include).Find(id);
}

这将急切地在我的实体右侧加载一个导航属性。

但如果我的实体看起来像这样:

public class Blog : PrimaryKey
{
    public Author Author {get;set;}
    public ICollection<Post> Posts {get;set;}
}

如何获得 AuthorPosts 的即时加载?我真的必须这样做吗:

_dbContext.Set<T>().Include("Author").Include("Posts").Find(id);

不可避免地会产生这样的功能:

T EagerGetById<T>(Guid id, string include, string include2, string include3) where T : class
{
    return _dbContext.Set<T>().Include(include).Include(include2).Include(include3).Find(id);
}

因为这对于 Generic 存储库来说效率非常低!

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    如果您不想使用字符串,您也可以使用返回要预先加载的导航属性的表达式对任意 N 个包含执行相同操作。 (原文来源here

    public IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties) 
    {
       IQueryable<TEntity> queryable = GetAll();
       foreach (Expression<Func<TEntity, object>> includeProperty in includeProperties) 
       {
          queryable = queryable.Include<TEntity, object>(includeProperty);
       }
    
       return queryable;
    }
    

    【讨论】:

    • 我实际上是在考虑这样做,但是在存储库模式中使用 DI 和 IoC 容易吗??
    • 第二眼... context.Configuration.ProxyCreationEnabled = false;不强制急切加载。它只是代理创建的轮流。你仍然需要做包含。我正在编辑它的答案。
    • 这有意义吗....启用代理创建有什么意义,它有什么好处?!
    • 代理创建可以延迟加载虚拟属性。本质上,EF 将为访问时访问数据库的导航属性放置“站在类中”。如果未启用代理生成,则那些尚未“包含”在查询中的子对象将显示为 null,并且 EF 不会在后台访问 db 进行延迟加载。
    • 我很难理解这个实现。能举个使用例子吗?
    【解决方案2】:

    如果您需要所有导航属性,您别无选择,只能从数据库中读取所有这些属性。您要么在查询中Include 它们,要么提前将它们读取到 DbSet 的本地数据中。

    如果您想将多个包含传递给您的方法,只需像这样定义它:

    T EagerGetById<T>(Guid id, params string[] includes)
    

    您的用户将能够致电EagerGetById(id, "inc1", "inc2", ...)

    在您的方法中,只需为 includes 数组中的每个元素调用 Include

    你应该准备好the params keyword

    【讨论】:

    • 查看编辑,特别是必须为此创建的新功能...
    • 哦,这不是低效,只是丑陋。我将编辑我的回复。
    • 我对参数一无所知.. 仍然没有真正回答这个问题!对不起,伙计,这还没有成功!
    • 作为记录,@zmbq 的回答很好。看来你没明白。公认的答案几乎是一回事。可以说,使用属性引用而不是属性名称更“干净”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2016-11-21
    • 2021-11-26
    相关资源
    最近更新 更多