的DbContext需要导航性能手动负载 [英] DbContext requires manual load of navigation properties

查看:212
本文介绍了的DbContext需要导航性能手动负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近升级了我的解决方案,从EF5到EF6.1.2,并改变了我使用的DbContext而不是ObjectContext的数据访问层。

I recently upgraded my solution from EF5 to EF6.1.2, and changed my data access layer to use DbContext instead of ObjectContext.

我的一些单元测试失败了,我不明白为什么。旧的数据访问code例:

Some of my unit tests are failing, and I don't understand why. Example of old data access code:

public virtual T Insert(T item)
{
        if (item == null)
        {
            throw new ArgumentNullException("item", @"TaskDal.Insert");
        }

        using (var ctx = ObjectContextManager<StoreDataContext>.GetManager("StoreDataContext"))
        {
            var task = new Task();
            WriteNonKeyData(task, item);
            ctx.ObjectContext.Tasks.AddObject(task); // task.taskType null
            ctx.ObjectContext.SaveChanges(); // task.TaskType set
            return ReadData(task);
        }
}

工作实体导航属性任务类型。如上评论,这得到了ADDOBJECT行之后设置。

The Task Entity has a navigation property TaskType. As commented above, this gets set after the AddObject line.

我的新code看起来像这样:

My new code looks like so:

public virtual T Insert(T item)
{
        if (item == null)
        {
            throw new ArgumentNullException("item", @"TaskDal.Insert");
        }

        using (var ctx = DbContextManager<StoreDataContext>.GetManager())
        {
            var task = new Task();
            WriteNonKeyData(task, item);
            ctx.DbContext.Tasks.Add(task); // task.TaskType null
            ctx.DbContext.SaveChanges(); // task.TaskType still null
            return ReadData(task);
        }
}

与旧code, task.TaskType 未设置,这将导致在 READDATA 异常。 LazyLoading是两个例子中真。

Unlike the old code, task.TaskType is not set, which causes an exception in ReadData. LazyLoading is true in both examples.

我可以通过手动重装解决此的任务类型

I can workaround this by manually reloading the TaskType:

if (task.TaskType == null)
    ctx.DbContext.Entry(task).Reference(p => p.TaskType).Load();

但我想preFER一个更好的解决方案,因为我相信有数以百计的其他地方,在我的code其中,这将需要被改变,这将是我很难找到他们。

but I would prefer a better solution, as I am sure there are hundreds of other places in my code where this will need to be changed and it will be difficult for me to find them all.

推荐答案

工作,因为它们不执行被延迟加载不会加载它的导航性能。看看你的类定义,你看到任何code吸气剂?没有。

Task will not load its navigation properties as these are not implemented to be lazily loaded. Take a look at your class definition, do you see any code in the getter? No.

现在,来看看你的旧的code自动创建的模型类,是有一个支持延迟加载一个非空吸?是的,有。

Now, take a look at the model classes created automatically for your legacy code, is there a non empty getter that supports lazy loading? Yes, there is.

不同的是,用code-第一,你的模型类没有code表示支持延迟加载。延迟加载仅在代理是由当你从数据库中检索数据的上下文中创建对象的支持。

The difference is that with code-first, your model classes have no code that supports lazy loading. Lazy loading is supported only on proxy objects that are created by the context when you retrieve data from the database.

一个简单的解决方法是将强制EF创建一个代理为你:

One of simplest workarounds would be to force the EF to create a proxy for you:

    using (var ctx = DbContextManager<StoreDataContext>.GetManager())
    {
        var task = new Task();
        WriteNonKeyData(task, item);

        ctx.DbContext.Tasks.Add(task); // task.TaskType null
        ctx.DbContext.SaveChanges(); // task.TaskType still null

        // let ef create a proxy for the very same database object
        var ptask = ctx.DbContext.Tasks.First( p => p.ID == task.ID );

        // ptask.TaskType is now available as the actual type of
        // ptask is not Task but rather a TaskProxy that inherits from Task
        // and is created automatically by ef

        return ReadData(ptask);
    }

这篇关于的DbContext需要导航性能手动负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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