【问题标题】:EntityException thrown executing EF6 query with .Includes()使用 .Includes() 执行 EF6 查询时抛出 EntityException
【发布时间】:2013-10-29 14:06:12
【问题描述】:

我在将 EF4 解决方案迁移到 EF6 时遇到问题。

我们使用 T4 模板生成具有基于 ObservableCollection 的导航属性的持久无知 POCO。

因为我们的 ObjectContext 实现将实体集公开为 IObjectSet,我们从 ObjectQuery 中丢失了 Include() 方法,因此必须在 IQueryable 上使用扩展方法来重新获得它,如下所示:

public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, string path)
{
    IQueryable<TSource> returnValue = source;
    var objectQuery = source as ObjectQuery<TSource>;

    if (objectQuery != null)
    {
        returnValue = objectQuery.Include(path);
    }

    return returnValue;
}

更新了使用 EF6 的解决方案后,我们现在在使用 .Include() 执行查询时看到以下 System.Data.Entity.Core.EntityException:-

“'DataEntities.Parent' 类型实体上的导航属性 'Details' 必须实现 ICollection,以便 Entity Framework 能够跟踪集合中的更改。”

我没有得到的是“详细信息”属性是一个自定义类型,它继承了作为 ICollection 的 ObservableCollection,那么为什么声明它必须实现 ICollection 的异常呢?

如果有人对此有任何启示,我将不胜感激,谢谢。

【问题讨论】:

  • 令人惊讶的是,当您提出问题时,答案通常会呈现出来!基本上,我们的导航属性被定义为 ObservableCollection。似乎不再支持将集合类型定义为接口。只需将它们更改为 ObservableCollection
  • 一个不同的问题,但这个链接 - link - 提供了缺失的部分。

标签: c# entity-framework entity-framework-6


【解决方案1】:

正如blogpost of an EF team member中所解释的那样

您的类必须遵循以启用更改跟踪代理的规则非常严格和限制性。这限制了您定义实体的方式并阻止使用私有属性甚至私有设置器之类的东西。

规则是:

  • 类必须是公开的,而不是密封的。
  • 所有属性都必须具有公共/受保护的虚拟吸气剂和 二传手。
  • 必须将集合导航属性声明为 ICollection。 它们不能是 IList、List、HashSet 等。

this answer 解释为什么你不能使用你的实现。

【讨论】:

  • 感谢您花时间回答我的帖子。我们使用的是快照更改跟踪,而不是更改跟踪代理,这只会增加异常引发的混乱。发现我们不能再将导航属性定义为 IEntity 类型的集合,而必须将它们定义为 Entity 类型的集合,我们的实现又恢复了业务。
猜你喜欢
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多