开发者

Entity framework and inheritance: NotSupportedException

I'm getting

System.NotSupportedException: All objects in the EntitySet 'Entities.Message' must have unique primary keys. However, an instance of type 'Model.Message' and an instance of type 'Model.Comment' both have the same primary key value

but I have no idea what this means.

Using EF4, I have a bunch of entities of type Message. Some of these messages are actually a subtype, Comment, inheritance by table-per-type. Just

 DB.Message.First();

will produce the exception. I have other instances of subtyping where I don't experience problems but I can't see any discrepencies. Sometimes, though, the problem goes away if I restart the development server, but not always.

Edit: I've worked out (should have before) that the problem is a fault of the stored procedure fetching my Messages. The way this is currently set up as that all the fields pertaining to Message is fetched, the Comment table is ignored by the sproc. The context then proceeds to muck this up, probably by fetching those Messages that are also Comments again, as you suggested. How to do this properly is the central issue at hand. I've found some indications to a solution at http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityfr开发者_开发技巧amework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602.


As you infer, it looks like the Context is fetching a Comment as a Message (not knowing that it is a comment). Later, you ask for the actual Comment, so the context fetches the Comment. Now you have two object instances in the Context with the same ID - one is a Message and one is a Comment.

It seems that the exception is not being thrown until after both objects have been loaded (ie when you try to access the Message the second time). If you can find a way to remove the Message from Context when the Comment is loaded, this may solve your problem.

Another option might be to use the Table-per-hierarchy model. This results in a bad database design but at the end of the day you have to use what works.

You might be able to avoid the problem by ensuring that the objects are loaded as Comments first. This way, when you ask for the Message, the Context already knows about it.

Also consider using Composition over Inheritance, such that a Message has 0..1 CommentDetails.

The final suggestion is to remove the dependency on the Entity Framework from your Control code, and create a Data Access Layer which references the EF and retrieves your objects. The DAL can turn Entity Framework objects into a different set of Entity objects which are easier to use in code. This approach will produce a lot of code overhead, but may be suitable if you cannot use the Entity Framework to produce an Entity model which represents your Entities in the way you want to work with them.

To summarize, unless MS fix this issue, there is no solution to your problem which does not involve a rethink of your approach. Unfortunately the Entity Framework is not ideal, especially for complex Entity models - you might be better off creating your own DAL and bypassing the EF altogether.


It sounds like you are pulling two records into memory one into message and one into comment.

Possible prblems:

  • There are two physical messages with the same id
  • The same message is being pulled up as a message and a comment
  • The same message is being pulled up twice into the same context

That the problem sometimes goes away when you restart, points to a problem with cleaning up of context. Are you using "using" statements.

Do you have functionality for changing from a message to a comment?


I am not an EF kind of guy (busy working with NHibernate, haven't had time to get up to date with EF yet) so I may be totally wrong here, but could the problem be that the two tables (since you are using inheritance by table-per-type) have primary keys that collide?

If you check the data in both tables, do primary key values collide?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜