1

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

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

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

谢谢

4

3 回答 3

2

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

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

    // more ...
}

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

现在,假设您启用了延迟加载AddressStatusLookup,并为实体分配了一个新的Person(setter 被调用,因此调用了 fixup 方法):previousValue.Persons.Something...导致延迟加载对数据库运行查询,该查询加载所有具有 aAddressStatusLookup值的人previousValue- 这是与您的数以百万计的人和只有 50 个统计数据一样,可能完全执行之前加载的数千或数十万人记录的列表Contains

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

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

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

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

于 2011-06-15T18:21:22.530 回答
1

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

编辑:可以在这里找到更多关于正在发生的事情的解释http://blogs.msdn.com/b/efdesign/archive/2010/03/10/poco-template-code-generation-options.aspx

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

于 2011-06-15T18:20:28.773 回答
0

对于该特定操作设置 Context.ContextOptions.LazyLoadingEnabled = false; 保存完成后将其重置为true。

于 2014-10-06T13:00:40.703 回答