实体框架5添加具有其他外键关系的实体和子实体

时间:2013-11-01 12:04:06

标签: c# entity-framework entity-framework-5

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

1 个答案:

答案 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文档的预期。