实体框架外键跟踪导致问题
本文关键字:问题 跟踪 框架 实体 | 更新日期: 2023-09-27 17:58:13
使用EF4,VS 2010中的模型优先方法:
考虑以下EntityModel:
"OrderBase"是一个抽象实体,只有一个属性"Name"
"Detail"(具有一个属性"Text")是一个与"OrderBase"有多对一关联的实体(即一个OrderBase有多个Details)
"Comment"(具有一个属性"Text")是一个与"OrderBase"有多对一关联的实体(即一个OrderBase有多个Comments)
"MusicOrder"是从"OrderBase"派生的实体,只有一个属性"Quantity"(int)
"SongOrder"是从"OrderBase"派生的实体,只有一个属性"Length"(int)。SongOrder与MusicOrder有多对一关系(即一个MusicOrder具有多个SonOrders)
快速概述:我想发布datamdel的图片,但我不被允许。。。关于数据模型的任何问题。
因此,现在我生成数据库,执行ddl脚本,并尝试运行以下代码:
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();
}
在这种情况下,"SaveChanges"会导致一个异常,告诉我一些关于缺少外键关系的信息。。。
但是如果我移动
container.OrderBaseSet.AddObject(songOrder);
在"清除"之后-产生以下代码的部分:
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();
}
一切都很好。
正如你所看到的,我知道如何绕过这个例外,我知道"双重添加"SongOrder是没有意义的。但我想知道这是一个bug还是一个功能。为什么在我的第一个例子中抛出异常。非常感谢您的全面解释。在我看来,实体框架也应该能够处理第一个例子,而不是抛出异常。所以我认为这是一个bug。
欢迎发表评论;)
Andi
之所以会发生这种情况,是因为调用AddObject
不会只添加单个实体,而是添加所有未附加到上下文的相关实体。因此,当您在第一个示例中调用AddObject(songOrder)
时,您还添加了Detail
和Comment
。但在此之后,您可以在导航属性上调用Remove
来删除Detial
和Comment
。附加实体上的Remove
只会破坏关系,但不会从上下文中删除Detail
和Comment
(它只会将它们的主要关系设置为null),所以一旦您尝试调用SaveChanges
,它就会爆炸,因为您试图在没有关联OrderBase
的情况下保存Detail
和Comment
(我想关系是不可为null的)。
在第二个示例中,Comment
和Detail
在向上下文添加顺序之前被删除,因此其行为符合预期。
这不是一个bug,而是一个"特性"。
您不必将歌曲顺序添加到基础中。只需将歌曲添加到音乐中,然后将音乐添加到基础音乐中即可。
最有可能的是不喜欢你添加与音乐无关的歌曲。