EF 6懒惰加载禁用,但儿童记录负载无论如何

我先使用EF6代码。 有两个表, LessonLessonSectionsLessonSections表具有LessonSections的外键

这是Lesson类,没有删除任何重要字段:

 public partial class Lesson { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Lesson() { LessonSections = new HashSet(); } [StringLength(50)] public string Id { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection LessonSections { get; set; } } 

以下是我启动数据模型的方法:

  var db = new Touch_Type_Trainer_DB.DataModel(); db.Configuration.ProxyCreationEnabled = false; db.Configuration.LazyLoadingEnabled = false; 

在我第一次调用数据库以检索数据库中的第一课后,生成的对象没有LessonSections

在第二次通话之前

然后我再次调用将这些部分检索到一个单独的对象中。 (它们必须位于单独的对象中,因为我想将它们序列化为JSON字符串,并且如果我使用标准EF LessonSections则序列化程序会停止LessonLessonSections之间的循环引用。)

第二次通话后

现在我的原始对象有两个从数据库加载的部分,即使我从未访问过LessonSections属性,即使LessonSections设置为False!

为什么要加载LessonSections

编辑:

我正在使用Newtonsoft将我的对象序列化为JSON字符串。 也许我应该设置Newtonsoft中的配置设置,以便它不会陷入循环引用问题?

此外,我确实希望为大多数代码启用LazyLoading,而不是为序列化部分启用。

对你来说这是一个问题,还是你只是好奇它为什么会发生?

DBContext会为您跟踪所有引用。 当您加载这些部分时,它知道课程中有对它们的引用,并为您连接它。

你可以通过断开对象,或从不同的dbcontext加载部分来阻止这种情况

 myDbContext.Entry(someLesson).State=Detached; 

有关序列化问题,请参阅此问答如何使用Newtonsoft.Json“真正”序列化循环引用对象?

要么

http://johnnycode.com/2012/04/10/serializing-circular-references-with-json-net-and-entity-framework/

在我看来,这是EF的不良行为。

EF以这种方式工作(就像您已经注意到的那样):当您禁用延迟加载关系时,未解析(即使您访问该属性也不会加载属性)。 在您的情况下,您可以访问les.LessonSections,您会看到null或(在您的情况下,您在Lesson构造函数中初始化它)为空。

如果您使用相同的上下文访问对象或未加载延迟加载的集合(构建查询并实现它),EF会自动尝试在延迟加载期间解决关系(如果对象没有代理)。 这是您的行为,在完全不同的查询中,您可以访问LessonSections和EF解决课程中的关系。

起初看起来是一个很好的行为,但最后你可能会有一个不一致的上下文(一些关系解决了,另一些没有解决),它可能导致一个有缺陷的应用程序。 恕我直言,如果EF(禁用LazyLoad)根本不解决关系,并且如果你需要解决它,你可以手动完成,行为可以更加一致。 但这只是我的意见。

关于您的问题,您可以像在另一个答案中建议的那样分离对象,或者在同一工作单元中使用两个不同的上下文(具有相同或不同的连接)。 我更喜欢(通常我使用)第二种方法,尽快处理禁用Lazy Load的上下文。