2016-08-16 63 views
1

我在EF中定义了以下对象:识别和删除实体框架子记录

public class ItemA() 
{ 
     public virtual ICollection<ItemB> Items{ get; set; } 
} 

public class ItemB() 
{ 
     public virtual ICollection<ItemC> Items{ get; set; } 
} 

在我的代码中,我做了以下操作;

myItemA.Items.Remove(myItemA.Items.FirstOrDefault(x => (int)x.Type == model.Type)); 

myItemA.Items.Add(new ItemB()); 

当填充意达的实例,它包含一个单一的ItemB,我只是想用ItemB的新实例来代替这一点。当我进入我的服务来更新消息时,我发现只需调用以下代码就会生成新的ItemB,而现有的ItemB将变为孤立状态,并且父ID为null。 ItemB和ItemC之间的链接完好无损。

_dbContext.Entry(entity).State = EntityState.Modified; 
_dbContext.SaveChanges(); 

所以,我知道我需要告诉EF这ItemB是孩子被删除,在模型中的约束,建立将有望级联删除子ItemC记录,然后孤立ItemB。但是,我正在努力寻找一种方法。

我已经尝试从上下文中重新获取Parent ItemA来比较List并将它们标记为已删除,但是当我获取代理时,两个对象基本上都是相同的,只有已更新的ItemB而不是原版的。

var existingItem = GetItem(entity.Id); 

var existing Items = GetItem(entity.Id).Items.ToList(); 

所以我需要的是原来ItemA.Items到能够告诉EF他们将被删除。请注意,我知道如何告知EF应该删除某些内容,我只想获得对应该删除的实体的引用。

编辑

添加该代码使得它的工作和孤儿ItemB(有孩子ItemC)现在被删除,但是,据我了解,现在将在2个交易完成。

//Update Message 
    _dbContext.Entry(entity).State = EntityState.Modified; 
    _dbContext.SaveChanges(); 

    //Remove any orphaned records 
    var itemsToRemove = _dbContext.Set<ItemB>().Where(x => x.ItemA == null).ToList(); 
    _dbContext.Set<ItemB>().RemoveRange(itemsToRemove); 
    _dbContext.SaveChanges(); 

理想的情况下,寻找一种方式来做到这一点单SaveChanges()

+0

您是否尝试过设置实体状态为删除? (item.Items中的var childitem)dbContext.Entry(childItem).State = EntityState.Deleted;'? –

+0

这是问题,item.Items不包含我想删除的项目,它只有新的itemB,它被添加,留下原始的ItemB孤儿。 – ChrisBint

+0

我的意思是在你删除并重新添加之前。但是你试图用下面的行删除? 'item.Items.Remove(item.Items.FirstOrDefault(x =>(int)x.Type == model.Type));'你在哪里获得物品?从数据库? –

回答

0

嗯..我才明白什么不对或者你只是想实现一个级联删除这样的:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<ItemB>().HasRequired(b => b.Parent).WithMany(a => a.Items).WillCascadeOnDelete(); 
} 

这也应该工作:

public class ItemA() 
{ 
    public virtual ICollection<ItemB> Items{ get; set; } 
} 

public class ItemB() 
{ 
    [Required] // This set's the constraint 
    public virtual ItemA Parent { get; set; } 
    public virtual ICollection<ItemC> Items{ get; set; } 
} 

没有使用第二个,但它应该有相同的结果。