locked
Strange error with Table Per Type inheritance RRS feed

  • Question

  • Hi,
    We have a mapping which implements TPT inheritance. We have a base table, Actions, with a PK ID and a few fields, and then several child tables with a PK ActionID and a variety of additional fields. We've mapped this according to the MSDN how to setup TPT article (http://msdn.microsoft.com/en-us/library/bb738685.aspx), and I've checked the EDMX file and it all appears to match what's in this example. From a designer point of view we set the base table, removed the existing association, removed the ActionID property from the child, then mapped the ActionID column to the ID property. Everything looks right.

    Our problem occurs whenever we try to load an Action though, either explicitly or through a navigation property. For example:

        Dim list = (From item In session.ActionSet).ToList
    

    This produces the following error and stack trace:

    System.InvalidOperationException:
     The EntityKey property can only be set when the current value of the property is null.
       at System.Data.Objects.ObjectStateEntry.GetAndValidateChangeMemberInfo(String entityMemberName, Object complexObject, String complexObjectMemberName, StateManagerTypeMetadata& typeMetadata, String& changingMemberName, Object& changingObject)
       at System.Data.Objects.ObjectStateEntry.EntityValueChanging(String entityMemberName, Object complexObject, String complexObjectMemberName)
       at System.Data.Objects.DataClasses.EntityObject.set_EntityKey(EntityKey value)
       at lambda_method(ExecutionScope , Shaper )
       at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
       at lambda_method(ExecutionScope , Shaper )
       at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
       at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

    Can anyone suggest what might be going on? I can upload the EDMX contents if required, but there's a lot of unrelated stuff in it as well, so I don't wnat to post a huge file if there's an obvious answer to this.

    Thanks,
    Kev
    Wednesday, September 23, 2009 9:39 AM

Answers

  • Ha, spotted it. I put together a simple test project but it didn't show the problem. Compared the various bits of the EDMX with the same bits in the live project and couldn't see any differences. Added in a few more tables, leading to associations in the model, but still no problems, and no significant differences in the EDMX. Tried a few other things, but still no problems. At this point I figured it must be something in the project code somewhere, so started having a good look at it (it's a project that one of my colleagues is working on). I noticed the following code in the partial class for each child entity:

        Public Sub New()
          ActionType = Fetch(enActionTypes.RunProgram)
        End Sub
    
    ActionType is a navigation property, and fetch returns an instance of the entity it refers to. Comment these constructors out and it all works.

    My guess as to what happens is that we start to materialise a child entity, and as part of this we call the constructor. The constructor loads an ActionType entity and tries to assign it to the navigation property in the class its about to materialise. This causes us to add our action entity to the context as well, and sets something in the entity key. Control then returns to the materialiser, which attempts to set the entity key, and bang! Sound plausible?

    Kev
    • Marked as answer by Kevin O Donovan Thursday, September 24, 2009 10:57 AM
    Thursday, September 24, 2009 10:47 AM

All replies

  • Hi Kevin,

     

    Welcome to MSDN forums!

     

    Based on my research, the error message is not a common one which makes it hard to reproduce.

     

    There is a blog about TPT in MSDN blogs:

    http://blogs.msdn.com/bags/archive/2009/03/06/entity-framework-modeling-table-per-type-inheritance.aspx

    (For converting C# code to VB

    http://www.developerfusion.com/tools/convert/csharp-to-vb/)

     

    Would you mind following this blog?

     

     

    If this blog doesn’t solve your problem, please give more description of your project.

     

    1) What are the differences between your project and this blog.

    For example, the tables’ schemas, condition values and the manipulations you do.

     

    2) Could you build your project successfully?

     

    3) Have you done any manipulation before using ToList?

     

     

     

    You can also send me email with your sample project. I’ll be more than happy to be of assistance.

    My email address is v-mofeng AT Microsoft DOT com.

     

     

    Have a great day!

     

     

    Best Regards

    Yichun Feng

     

     

    This response contains a reference to a third party World Wide Web site. Microsoft is providing this information as a convenience to you. Microsoft does not control these sites and has not tested any software or information found on these sites; therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information found there. There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, September 24, 2009 6:18 AM
  • Hi Yichun,
    I've taken a look at that article, and the only thing I can see that we did differently was to add the inheritance before removing the association, whereas the article did it the other way round. I'm going to create a new test project and model using just the base table and a couple of the child tables. I'll try doing it in the same order as the article, and if I still get the error I'll take you up on your offer and send the project to you for a once over, if that's okay?

    I'll report back later,

    Thanks,
    Kev
    Thursday, September 24, 2009 10:02 AM
  • Ha, spotted it. I put together a simple test project but it didn't show the problem. Compared the various bits of the EDMX with the same bits in the live project and couldn't see any differences. Added in a few more tables, leading to associations in the model, but still no problems, and no significant differences in the EDMX. Tried a few other things, but still no problems. At this point I figured it must be something in the project code somewhere, so started having a good look at it (it's a project that one of my colleagues is working on). I noticed the following code in the partial class for each child entity:

        Public Sub New()
          ActionType = Fetch(enActionTypes.RunProgram)
        End Sub
    
    ActionType is a navigation property, and fetch returns an instance of the entity it refers to. Comment these constructors out and it all works.

    My guess as to what happens is that we start to materialise a child entity, and as part of this we call the constructor. The constructor loads an ActionType entity and tries to assign it to the navigation property in the class its about to materialise. This causes us to add our action entity to the context as well, and sets something in the entity key. Control then returns to the materialiser, which attempts to set the entity key, and bang! Sound plausible?

    Kev
    • Marked as answer by Kevin O Donovan Thursday, September 24, 2009 10:57 AM
    Thursday, September 24, 2009 10:47 AM
  • Out of interest, I got this working for him as intended by modifying his constructors to set the entity key rather than the reference itself. It works, but it's a bit icky. Could I have just defined the discriminator in the model, and it would all have been handled automatically?

    Kev
    Thursday, September 24, 2009 11:00 AM