【问题标题】:EF4 slow association accessEF4慢关联访问
【发布时间】:2011-02-08 14:01:08
【问题描述】:

我正在使用 EF4 构建一个 ASP.NET 4 Web 应用程序,并且我有这样的表:

产品
属性

Product_Attribute_Map

Product_Attribute_Map 是一个多对多的交叉表。所以 Product 可以有零个或多个属性,反之亦然。

在代码中我这样做:

//Attribute a = new Attribute(); // Edit:
Attribute a = (from a in context.Attributes where a.AttributeID = 1 select a).First();
a.Name = "test"; 
Product.Attributes.Add(a);

我注意到一个问题,这使得这非常慢。 EF4 将在服务器上执行此 SQL:

SELECT 
[Extent2].* FROM  [dbo].[Product_Attribute_Map] AS [Extent1]
INNER JOIN [dbo].[Product] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
WHERE [Extent1].[AttributeID] = @p1

我不明白为什么会这样。一个属性可能被分配给 10.000 个产品,这使得这是一个错误的查询。将属性添加到产品需要超过 5 秒...

如何防止 EF4 选择所有属性?只需选择该产品的属性即可。

谢谢

编辑:这仅使用 POCO t4 模板。 EntityObject 模板没有这个问题。

【问题讨论】:

  • 看起来 EF 正在尝试在您的属性上填充 Products 集合。您的表映射是什么样的?
  • 你是否开启了延迟加载?你可能不想要它在这里。它不会帮助显示的代码。不试一下。
  • 开启延迟加载,导致SQL查询执行。如果我关闭它,其他现有映射将在保存时删除(因为它们不在集合中)
  • 我感觉这里就像是盲人在带领盲人(没有 EF POCO 经验)。您是否启用了代理创建?
  • 是的,POCO T4 模板,启用延迟加载,启用代理。表之间的正常 0..* 到 0..*。我认为 Ladislav Mrnka 可能是正确的,它可能与关联修复方法有关。 POCO 生成干净的类,但它似乎订阅了导航集合属性的更改事件并进行了一些修复(以保持同步,但如果它要从数据库中选择所有记录,那是不值得的......)。

标签: asp.net c#-4.0 entity-framework-4


【解决方案1】:

我的猜测:这是因为 LazyLoading 与 POCO 模板生成的 FixUpCollections 一起使用。当您将属性添加到产品时,修复集合也会执行反向操作 - 它会将产品添加到属性,但首先访问属性中的产品集合将触发延迟加载,因此您的查询将被执行。我不喜欢修复集合...您可以修改 POCO 模板以不使用它们,或者您可以删除 Attribute 中的 Products 导航属性(如果您不需要它)。

【讨论】:

  • 你知道删除修复操作有什么缺点吗?
  • @peter:您将失去关系的双向同步。您的代码不必依赖它们。如果您将属性添加到产品,并且您还想在保存更改之前使用反向,则必须手动将产品添加到属性。您可以定义自己的不使用 FixUp 集合的 POCO 实体(在代码中很常见),因此它可以在没有它们的情况下工作。
  • 不幸的是,删除修复方法并没有解决问题。但是,您从 Attribute 中删除 Products 导航属性的提示使其速度更快。我想我会保持这种方式。但对我来说,为什么 EntityObject T4 没有这个问题是个谜。
猜你喜欢
  • 1970-01-01
  • 2011-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多