我正在
System.NotSupportedException:全部 EntitySet中的对象 'Entities.Message'必须具有唯一性 主键。但是,一个例子 输入'Model.Message'和一个实例 类型'Model.Comment'都有 相同的主键值
但我不知道这意味着什么。
使用EF4,我有一堆Message类型的实体。其中一些消息实际上是一个子类型,注释,按类型继承。只是
DB.Message.First();
会产生异常。我有其他的子类型实例,我没有遇到问题,但我看不出任何差异。但是,有时候,如果我重新启动开发服务器,问题就会消失,但并非总是如此。
编辑: 我已经解决了(之前应该有的)问题是存储过程获取我的消息的错误。当前设置的方式是获取与Message相关的所有字段,sproc会忽略Comment表。然后上下文继续进行捣乱,可能是通过再次提取那些也是评论的消息,如您所建议的那样。如何正确地做到这一点是当前的核心问题。我在http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602找到了解决方案的一些迹象。
答案 0 :(得分:2)
正如您所推断的,看起来Context正在将Comment作为消息获取(不知道它是注释)。之后,您要求实际的注释,因此上下文将获取注释。现在,您在Context中有两个具有相同ID的对象实例 - 一个是Message,另一个是Comment。
似乎在加载两个对象之后(即第二次尝试访问Message时)才会抛出异常。如果您可以在加载注释时找到从上下文中删除消息的方法,这可以解决您的问题。
另一种选择可能是使用Table-per-hierarchy模型。这导致了糟糕的数据库设计,但在一天结束时你必须使用有效的方法。
您可以通过确保首先将对象作为“注释”加载来避免此问题。这样,当您要求消息时,上下文已经知道它。
还要考虑使用Composition over Inheritance,以便消息具有0..1 CommentDetails。
最后的建议是从Control代码中删除对Entity Framework的依赖,并创建一个引用EF并检索对象的数据访问层。 DAL可以将Entity Framework对象转换为更容易在代码中使用的不同Entity对象集。这种方法会产生大量的代码开销,但如果你不能使用实体框架来生成一个实体模型,它可以用你想要的方式来表示你的实体,那么它可能是合适的。
总结一下,除非MS修复此问题,否则您的问题没有解决方案,这不会重新考虑您的方法。不幸的是,实体框架并不理想,特别是对于复杂的实体模型 - 您可能最好创建自己的DAL并完全绕过EF。
答案 1 :(得分:1)
听起来你正在将两条记录拉入记忆中,一条记录在消息中,另一条记录在评论中。
可能的问题:
重新启动时问题有时会消失,指出清理上下文时出现问题。你在使用“使用”声明。
您是否具有从消息更改为评论的功能?
答案 2 :(得分:0)
我不是EF类型的人(忙于与NHibernate合作,还没有时间与EF保持同步)所以我在这里可能完全错了,但问题可能是两个表(因为你按照每个类型的表使用继承)主键是否会发生碰撞?
如果检查两个表中的数据,主键值是否会发生冲突?