2013-11-01 151 views
0

我使用实体框架(EF),5守则第一其它外键关系。实体框架5加实体和子实体与

我有一个自我参照的对象,我们称之为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; 
} 

是的,这也是自引用的,但这应该不重要。该数据库目前拥有基于这是由数据库迁移添加到Demo表的Item_Id的外键。数据库预填充了一组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

感谢@ArturoMartinez'的评论我能够正确地关注问题,并且我添加了一个答案。 – Boggin

回答

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文档。