使用dbcontext和投影进行预先加载

时间:2015-02-15 15:31:40

标签: c# entity-framework dbcontext

我们正在将项目从ObjectContext转换为dbContext。 我们当前的问题在于如何处理急切的加载。

示例上下文

public class Person
{
    public virtual ICollection<Email> Emails { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}
public class Email
{
    public string Address{ get; set; }
}
public class Post
{
    public string Content{ get; set; }
}

我们在整个企业中有许多代码需要加载电子邮件,因此在不考虑的情况下调用person.Emails.First()。 所以我们需要确保Emails被急切加载。

有时我们可以只是Include

但是,当我们在数据层中使用投影时,我们遇到了问题。即。

return context.Persons.Select(p=> new Top5VM {
    Person = p,
    TopPosts = p.Posts.Take(5)
};

我们有很多代码依赖于Top5VM并希望加载Person.Emails

无论我们尝试了什么,我们都无法弄清楚将Include(或Load)函数调用放在何处会实际产生影响。

使用ObjectContext,我们在名为Top5VM的{​​{1}}上只有一个虚拟属性。一旦加载,ObjectContext就会引用所有这些Emails,因此即使我们通过person对象访问它们也不需要返回服务器。但这不再适用于DbContext

2 个答案:

答案 0 :(得分:1)

想出来。每当我想使用投影来完成急切加载时,我需要设置context.Configuration.LazyLoadingEnabled = false;。当然,除非我想直接从投影中访问加载的实体。

答案 1 :(得分:0)

您可以通过在中间使用自己的DbContext来完成此操作:

public class MyDbContext : DbContext
{
    public MyDbContext() : base()
    {
        Configuration.LazyLoadingEnabled = false;
    }
}

然后在任何地方使用此而不是DbContext

或者,如果您可以控制所有POCO,则可以从相关集合中删除virtual关键字... virtual关键字是Microsoft用于延迟加载的神奇连接。< / p>

修改

我也倾向于将此作为扩展方法:

static class DbContextExtensions
{
    public static DbContext AsEagerLoadingContext(this IDbContext context)
    {
        context.Configuration.LazyLoadingEnabled = false;
        //context.Configuration.AutoDetectChangesEnabled = false;

        return context;
    }
}

如此使用,允许根据需要使用或不使用延迟加载:

using (var context = new DbContext().AsEagerLoadingContext())
    context.Stuff.Select(s => s.AllTheThings);