我正在使用实体框架(EF)5 Code First。
我有一个自引用对象,我们称之为Demo
:
public class Demo
{
public int Id;
public string Name;
public Demo Parent;
public ICollection<Demo> Children;
public Item Item;
}
这引用了另一个对象Item
:
public class Item
{
public int Id;
public string Name;
public Item Parent;
public ICollection<Item> Children;
}
是的,这也是自我引用,但这无关紧要。数据库现在具有基于Item_Id
的外键,该外键由数据库迁移添加到Demo
表。数据库预先填充了一组Item
条记录(这是一组有限的记录)。
我的上下文已经很好地映射到数据库,我正在对新记录进行大量数据插入。还有一些代码用数据填充对象。这是通过EF的实际导入:
public void ImportDemo(IEnumerable<Demo> demos)
{
var context = this.UnitOfWork.MyApplicationContext;
foreach (var demo in demos)
{
this.DataSet.Add(demo);
context.Entry(demo).State = EntityState.Added;
}
// NOTE: expecting an empty db.
context.SaveChanges();
}
我的DbModelBuilder具有以下内容:
modelBuilder.Entity<Demo>()
.HasOptional(p => p.Parent)
.WithMany(p => p.Children);
modelBuilder.Entity<Item>()
.HasOptional(p => p.Parent)
.WithMany(p => p.Children);
我可以成功导入Demo
个实体,以及子Demo
个实体,但每个子Demo
个实体正在创建一个新的Item
数据库而不是仅链接到现有的Item
。父Demo
个实体没有Item
个记录,它们都是空的。
如何确保子Demo
个实体链接到现有Item
个记录而不是创建新记录?
答案 0 :(得分:0)
整个结构在业务层中设置并映射(AutoMapper)到相关模型。
Item
对象位于DbContext.IDbSet<Item>.Local
集合中,但模型中的虚拟Items
需要使用本地集合中的Item
对象重置,如下所示。 / p>
public void ImportDemo(IEnumerable<Demo> demos)
{
foreach (var demo in demos)
{
foreach (var child in demo.Children)
{
child.Item =
dbContext.Items.Local.First(p => p.Id == child.Item.Id)
}
dbContext.Set<Demo>.Add(demo);
}
dbContext.SaveChanges();
}
我尝试使用Attach()
,但它的行为并不符合MSDN文档的预期。