0

我正在使用实体框架 (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记录而不是创建新记录?

4

1 回答 1

0

整个结构在业务层中设置并映射(AutoMapper)到相关模型。

Item对象在DbContext.IDbSet<Item>.Local集合中,但模型中的虚拟对象需要使用本地集合中的对象Items进行重置,Item如下所示。

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 文档中的预期不同。

于 2013-11-04T14:46:26.827 回答