Entity framework 为什么DbSet.Add会更改其他实体的属性?
我有一个罕见的例子,调用Entity framework 为什么DbSet.Add会更改其他实体的属性?,entity-framework,ef-code-first,entity-framework-6,Entity Framework,Ef Code First,Entity Framework 6,我有一个罕见的例子,调用DbSet.Add()会更改DbSet中已有的其他实体的一些属性。不幸的是,这种情况很少发生,我仅有的证据是一些日志文件,所以我还不能在本地复制它 行为是这样的: 首先,我们使用LINQ查询从DbSet加载一些实体 然后,其中一些实体被更改。还没有SaveChanges() 现在我们通过调用DbSet.add()添加一些实体 步骤2的一些实体在步骤3中更改(它们的一个外键属性设置为null) 有什么想法吗?EF 6代码优先模型会发生这种情况吗 我能想到的唯一可能性是,Db
DbSet.Add()
会更改DbSet
中已有的其他实体的一些属性。不幸的是,这种情况很少发生,我仅有的证据是一些日志文件,所以我还不能在本地复制它
行为是这样的:
DbSet
加载一些实体SaveChanges()
DbSet.add()
添加一些实体null
)
有什么想法吗?EF 6代码优先模型会发生这种情况吗
我能想到的唯一可能性是,DbContext
刷新数据库中的一些数据,但我们现在不希望它这样做
EDIT:由于我们几个星期以来一直在追踪这个bug,因此代码目前散布在日志语句中。以下是相关的代码部分:
// parameter: List<Entry> entriesFromUser
var entriesFromDb = db.Entries
.Where(...)
.OrderBy(...)
.ToList();
var newEntries = MergeEntries(entriesFromDb, entriesFromUser);
var propertyBefore = entriesFromDb[0].MyForeignKeyId;
for (var i = 0; i < newEntries.Count; i++)
{
// make sure that the "new entry" is not a modified one
if (entriesFromDb.Contains(newEntries[i])
{
throw new Exception();
}
db.Entries.Add(newEntries[i]);
}
var propertyAfter = entriesFromDb[0].MyForeignKeyId;
Debug.Assert(propertyBefore == propertyAfter); // <=== fails sometimes
db.SaveChanges();
//参数:List entriesFromUser
var entriesFromDb=db.Entries
.其中(…)
.OrderBy(…)
.ToList();
var newEntries=MergeEntries(entriesFromDb,entriesFromUser);
var propertyBefore=entriesFromDb[0]。MyForeignKeyId;
对于(var i=0;i Debug.Assert(propertyBefore==propertyAfter);//D'oh.找到了原因。希望对其他人有所帮助
我们正在使用,这意味着我们同时拥有导航属性entry.MyForeignKey
和外键属性entry.MyForeignKeyId
,这有很多优点,但也意味着在使用这个、那个属性时必须小心
事实证明,我们在代码的深处有以下赋值,其中一个条目的所有数据都复制到另一个条目:
entry.MyForeignKeyId = otherEntry.MyForeignKeyId
entry.MyForeignKey = otherEntry.MyForeignKey
但是,在许多情况下,您将外键值设置为实体的MyForeignKeyId
,但将属性MyForeignKey
保留为null,因为未加载父实体。只要您不将null指定给实体的MyForeignKey
属性,这就可以了,因为这样EF就会将MyForeignKeyId
也设置为null
因此,似乎在我们的代码将null分配给MyForeignKey
之后,实体在内存中保留了nullMyForeignKey
和非nullMyForeignKeyId
,DbSet
注意到MyForeignKey
收到了一个null
赋值,因此DbSet
继续并将null
赋值给MyForeignKeyId
。请显示执行这些步骤的代码。我可以想象添加实体会改变FK值,但只有您的代码才能确认。呃嗯,是的,这并没有告诉我很多关于实体之间的关系。这里可能发生的是,一个新实体“窃取”了一个现有实体的引用。有关于这种“窃取引用”的文档吗?顺便说一句,我说的外键是N:1。你说的新实体“窃取”是什么意思来自现有实体的引用?是否记录了EF 6代码优先行为?如果现有B是现有a的子级,并且有一个新的C将B作为子级,则可能导致B获得不同的FK。