Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602.

like image 897
Martin Avatar asked Aug 01 '10 13:08

Martin


2 Answers

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.

like image 52
Greg Sansom Avatar answered Oct 05 '22 17:10

Greg Sansom


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?

like image 31
Shiraz Bhaiji Avatar answered Oct 05 '22 17:10

Shiraz Bhaiji