EF导航属性循环问题

时间:2011-06-15 16:46:29

标签: entity-framework-4 navigation-properties

我目前有一个看起来像这样的数据库

Person Table
Id
Name
AddressLookupTypeId


AddressLookupType Table
Id
Description
SortOrder

当我使用实体框架4.0的设计器并添加两个表时,我在两个类上都获得了导航属性,即:

Person Class
Id
Name
AddressLookupType - Nav Property


AddressStatusLookup Class
Id
Description
SortOrder
Person - Navigation Property

现在我的人员表有大约300多万条记录,地址类型只有大约50条左右的记录。 当我更新任何人的状态并因某种原因呼叫保存更改时,需要永远进行更新;如果我在代码执行过程中暂停和调试,我最终会在一个名为FixupAddressStatusLookup的方法中。 我不知道到底发生了什么,但它看起来像是循环遍历具有相同addressstatustype的Person记录的子集;这只是我最好的猜测。如果我从设计器中的AddressStatusLookup类中删除Person导航属性,而不是立即执行代码。 任何人都可以解释这里可能发生的事情吗?为什么在我的AddressStatusLookup上有Person的导航属性导致这样的延迟?

由于

3 个答案:

答案 0 :(得分:2)

您的修复方法看起来可能是这样的:

private void FixupAddressStatusLookup(AddressStatusLookup previousValue)
{
    if (previousValue != null && previousValue.Persons.Contains(this))
    {
        previousValue.Persons.Remove(this);
    }

    // more ...
}

AddressStatusLookup类的Person导航属性的设置器中调用它。

现在,假设您启用了延迟加载,并为AddressStatusLookup实体分配了一个新的Person(调用setter,因此修复方法):{{ 1}}导致延迟加载对数据库运行查询,该数据库加载所有previousValue.Persons.Something...值为AddressStatusLookup的人 - 这与您的数百万人有关,只有50个stati可能是数千个列表或在成为previousValue之前加载的数十万个人记录。

我不知道这些自动生成的修复方法如何与延迟加载兼容而不会导致此类问题。

要解决此问题,您可以尝试:

  • Contains课程中删除Person集合(正如您已成功尝试的那样)。无论如何,它的用处是值得怀疑的。
  • 或者:不要使用延迟加载
  • 或者:从生成的类中删除fixup方法。 (也许可以调整T4模板并创建一个自定义模板来抑制首先生成这些方法,但我不确定。)

(如果你没有启用延迟加载,这个答案可能完全没用。)

答案 1 :(得分:1)

这听起来像是在使用T4 POCO模板?如果是这样,你所看到的是运行的FixUp代码,它修复了从一端到另一端的关系。它基本上不适用于我发现的非平凡数据库,因为它遍历关系的许多端,以确保正确设置反向指针。您可以做的最好的事情是在上下文中关闭LazyLoading.ContextOptions并在需要时使用Include等加载关系。

编辑:可以在http://blogs.msdn.com/b/efdesign/archive/2010/03/10/poco-template-code-generation-options.aspx

找到有关正在发生的事情的更多解释

此外,ADO.NET SelfTrackingEntity Generator生成的对象没有延迟加载,因此也不要这样做。

答案 2 :(得分:0)

对于该特定操作,设置Context.ContextOptions.LazyLoadingEnabled = false;一旦完成保存,重置为真。