开发者

Entity framework foreign key tracking causes problem

working with EF4, model first approach in VS 2010:

Consider the following EntityModel:

"OrderBase" is an abstract entity with just one property "Name"

"Detail" (with one property "Text") is an entity that has a many to one association to "OrderBase" (i.e. one OrderBase has multiple Details)

"Comment" (with one property "Text") is an entity that has a many to one association to "OrderBase" (i.e. one OrderBase has multiple Comments)

"MusicOrder" is an entity derived from "OrderBase" with just one property "Quantity" (int)

"SongOrder" is an entity derived from "OrderBase" with just one property "Length" (int). SongOrder has a many to one relation to MusicOrder (i.e. one MusicOrder has multiple SonOrders)

For a quick overview: Wanted to post the image of the datamdel, but I'm not allowed... So any questions concerning the datamodel.

So now I generate my database, execute the ddl script and try to run the following code:

using (DataContainer container = new DataContainer())
{
    MusicOrder musicOrder = new MusicOrder{Name = "Oldies", Quantity = 1};
    SongOrder songOrder = new SongOrder {Name = "Great balls of fire", Length = 240};
    songOrder.Details.Add(new Detail{Text = "Song from Jerry Lee Lewis"});
    songOrder.Comments.Add(new Comment{Text = "Cool song"});

    container.OrderBaseSet.AddObject(songOrder); //relevant line
    musicOrder.SongOrders.Add(songOrder);

    songOrder.Details.Clear();
    songOrder.Comments.Clear();
    container.OrderBaseSet.AddObject(musicOrder);
    container.SaveChanges();
}

In this case "SaveChanges" leads to an exception telling me something about missing foreign key relations...

But if I move the line

container.OrderBaseSet.AddObject(songOrder);

after the "Clear"-part resulting in the following code:

using (DataContainer container = new DataContainer())
{
    MusicOrder musicOrder = new MusicOrder{Name = "Oldies", Quantity = 1};
    SongOrder songOrder = new SongOrder {Name = "Great balls of fire", Length = 240};
    songOrder.Details.Add(new Detail{Text = "Song from Jerry Lee Lewis"});
    songOrder.Comments.Add(new Comment{Text = "Cool song"});

    musicOrder.SongOrders.Add(songOrder);

    songOrder.Details.Clear();
    songOrder.Comments.Clear();

    container.OrderBaseSet.AddObject(songOrder); //relevant line
    container.OrderBaseSet.AddObject(musicOrder);
    container.SaveChanges();
}

everything works fi开发者_如何转开发ne.

As you can see I know how to come around the exception and I know it makes no sense to "double add" the SongOrder. But I'm wondering if this is a bug or a feature. Why is the exception thrown in my first example. Would really appreciate a comprehensive explanation. In my opinion, the entity framework should also be able to deal with the first example and not throw an exception. So I would say it's a bug.

Feel free to comment ;)

Andi


This happens because calling AddObject doesn't add only single entity but all related entities which are not attached to the context as well. So when you call AddObject(songOrder) in the first example you also add Detail and Comment. But after that you call Remove on navigation properties to remove both Detial and Comment. Remove on attached entities will only break the relation but it will not delete Detail and Comment from the context (it will only set their principal relation to null) so once you try calling SaveChanges it will blow up because you are trying to save Detail and Comment without associated OrderBase (I guess relations are non nullalbe).

In the second example Comment and Detail is deleted before you add order to the context so it behaves as expected.

It is not a bug it is a "feature".


you dont have to add songorder to base. just add song to music and then music to base.

Its most prob not liking you adding song thats not associated with music.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜