C# 在Entity Framework 6中从部分类显式加载的推荐方法是什么?

C# 在Entity Framework 6中从部分类显式加载的推荐方法是什么?,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,我正在从EF4升级到EF6,并正在进行突破性的更改。我在缺少.IsLoaded和.Load方法方面遇到了一些问题,这些方法显然不再可用。以前,我有一些代码来确保如果数据可用,它就会被加载,但不确定在升级到EF6时应该如何更改 EF4代码: if ((this.EntityState == EntityState.Modified) || (this.EntityState == EntityState.Unchanged)) { if (!this.AccountReference.I

我正在从EF4升级到EF6,并正在进行突破性的更改。我在缺少
.IsLoaded
.Load
方法方面遇到了一些问题,这些方法显然不再可用。以前,我有一些代码来确保如果数据可用,它就会被加载,但不确定在升级到EF6时应该如何更改

EF4代码:

if ((this.EntityState == EntityState.Modified) || (this.EntityState == EntityState.Unchanged)) 
{
    if (!this.AccountReference.IsLoaded)
    {
        this.AccountReference.Load();
    }
}

现在,
.EntityState
.IsLoaded
.Load
都丢失了。到目前为止,我所看到的提示是
上下文。[stuff]
,但是由于这是一个局部类,因此没有
上下文。[stuff]
供我使用。

我必须寻找其他的,但是
状态可以通过以下途径找到:

context.Entry(yourEFobject).State
其中
context
是您的
DbContext
实例

正如@GertArnold在他的评论中提到的,EF6中的实体对象是简单的POCO,所以您不能直接从它们读取状态等

这个答案似乎涵盖了
.IsLoaded
.Load

为了完整起见,该答案中的内容包括:

context.Entry(yourEntity)
   .Collection(entity => entity.NavigationProperty)
   .IsLoaded;

context.Entry(yourEntity)
   .Collection(entity => entity.NavigationProperty)
   .Load();

恭喜你!您使用了比以前更好的API。
DbContext
API优于较旧的
ObjectContext
API的原因有很多,但在您的情况下,一开始可能会感觉降级

哪里是我的
实体状态
,哪里是我的
参考
? 分离关注点是这里的关键。
DbContext
API旨在实现持久性忽略:业务逻辑和数据层关注点之间的分离。
ObjectContext
API生成的实体忙于跟踪自己的状态、加载自己的引用和集合以及通知自己的更改。任何业务逻辑都很容易与持久性逻辑纠缠在一起

DbContext
生成器生成的实体类是POCO。所有这些与数据相关的责任都转移到了变更跟踪器上。POCO可以专注于业务逻辑。(它们仍然与DDD域不同,但这是一个不同的讨论)

如果愿意,您仍然可以返回到
ObjectContext
API,但我不推荐使用它。您的代码表明API鼓励了不良做法:

  • 对象加载自己的引用或集合很容易导致N+1反模式(1个查询加载对象,每个对象后面跟着“N”个查询)
  • 为了让对象能够加载自己的数据,上下文必须是活动的,因此这鼓励使用长期存在的上下文反模式
DbContext
API鼓励您根据需要加载对象图,然后处理上下文。但这要视情况而定。在智能客户端应用程序中,每个表单可能有一个上下文。在web应用程序中,强烈建议使用每个请求的上下文

正如您在对Tieson T的评论中所说的,只要您访问导航属性并满足以下条件,您就可以依靠延迟加载,但上述反模式仍然适用


因此,我认为暂时可以让应用程序代码保持原样,但看看
DbContext
API鼓励您遵循的模式。就我而言,延迟加载几乎是一种反模式。

您是否也使用POCOs迁移到DbContext API?看起来我确实迁移到了DbContext,我试图保持“尽可能默认”,因此我通过删除.emdx并重新创建来重新创建(即,与我创建EF6之前的方式相同)。。。看起来这已更改为DbContext。不幸的是,在查找IsLoaded引用时,我没有可用的上下文,因此我无法执行context.[method]或context.[property]之类的操作。这是在以前的操作中完成的,以确保在访问分部类中的子对象之前加载它们,某种程度上是一种强制的延迟加载。。。在这种情况下(尽管我现在正在测试/确认)@ChrisHDog,删除部分类中所有IsLoaded if语句是否安全?我正在做你几年前做的同样的工作,我的部分课程也遇到了同样的问题。看起来我会没事的,如果部分类代码正在运行,那么对象确实被加载了,如果这有意义的话?@Mitch对响应延迟表示抱歉,但是是的,我们现在正在使用EF6,并且已经删除了所有IsLoaded和.Load项。仍然有可能未加载某些内容,但EF现在会在该点加载它们(因此,可以通过加载初始数据拉动。Include语句来实现潜在的性能调整;或者根据具体情况不加载)。我与海报处于相同的情况,从EF4转换为EF6。你是说我可以删除所有处理IsLoaded和.Load()的代码吗?如果实体自己这么做:是的。如果不是,那要看情况。在某些情况下,显式加载可能比即时加载(Include)或延迟加载更好。谢谢,听起来我需要更多的实体框架经验来真正理解何时需要其中之一。