Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 标识和删除实体框架子记录_C#_Entity Framework - Fatal编程技术网

C# 标识和删除实体框架子记录

C# 标识和删除实体框架子记录,c#,entity-framework,C#,Entity Framework,我在EF中定义了以下对象: public class ItemA() { public virtual ICollection<ItemB> Items{ get; set; } } public class ItemB() { public virtual ICollection<ItemC> Items{ get; set; } } 填充ItemA实例时,它包含一个ItemB,我只想用ItemB的新实例替换它。当我进入我的服务来更新

我在EF中定义了以下对象:

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

public class ItemB()
{
        public virtual ICollection<ItemC> Items{ get; set; }
}
填充ItemA实例时,它包含一个ItemB,我只想用ItemB的新实例替换它。当我进入我的服务来更新消息时,我注意到仅仅调用以下代码就会导致新的ItemB和现有的ItemB成为孤立的,父ID为null。ItemB和ItemC之间的链接是完整的

_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
因此,我知道我需要告诉EF子项B将被删除,并且模型中设置的约束将希望级联删除子项C记录,然后是孤立项B。然而,我正在努力找到这样做的方法

我曾尝试从上下文中重新获取父项A,以比较列表并将其标记为已删除,但当我获取代理时,这两个对象本质上是相同的,只有更新的项B,而不是原始项B

var existingItem = GetItem(entity.Id);

所以我需要的是原始ItemA.Items,以便能够告诉EF它们将被删除。请注意,我知道如何告诉EF应该删除某些内容,我只对获取应该删除的实体的引用感兴趣

编辑

添加此代码使其工作,孤立项B(带有子项C)现在被删除,但是,据我所知,这将在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();
//更新消息
_dbContext.Entry(entity.State=EntityState.Modified;
_dbContext.SaveChanges();
//删除任何孤立记录
var itemsToRemove=_dbContext.Set(),其中(x=>x.ItemA==null.ToList();
_dbContext.Set().RemoveRange(itemsToRemove);
_dbContext.SaveChanges();

理想情况下,寻找一种方法来实现这一点,只需一次
SaveChanges()

嗯。。我是否理解了一些错误,或者您是否只想实现如下级联删除:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ItemB>().HasRequired(b => b.Parent).WithMany(a => a.Items).WillCascadeOnDelete();
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().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; }
}
公共类ItemA()
{
公共虚拟ICollection项{get;set;}
}
公共类ItemB()
{
[必需]//此集合是约束
公共虚拟项父项{get;set;}
公共虚拟ICollection项{get;set;}
}

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

嗯。。我是否理解了一些错误,或者您是否只想实现如下级联删除:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ItemB>().HasRequired(b => b.Parent).WithMany(a => a.Items).WillCascadeOnDelete();
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().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; }
}
公共类ItemA()
{
公共虚拟ICollection项{get;set;}
}
公共类ItemB()
{
[必需]//此集合是约束
公共虚拟项父项{get;set;}
公共虚拟ICollection项{get;set;}
}

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

是否尝试将实体状态设置为“已删除”
foreach(item.Items中的var childitem)dbContext.Entry(childitem.State=EntityState.Deleted?这就是问题所在,项目。项目不包含我要删除的项目,它只有新的项目B,该项目已添加,原始项目B处于孤立状态。我的意思是在删除和重新添加之前。但是你想用下面这行删除什么呢<代码>item.Items.Remove(item.Items.FirstOrDefault(x=>(int)x.Type==model.Type))您从何处获取项目?从数据库?我不想触及我的控制器方法中的上下文(调用该方法的地方)。我打算在某个时候从UI层完全抽象EF实体。代码的目的是删除类型匹配的任何记录(和子记录),基本上意味着您只能拥有该类型中的一个。这是对现有数据库的重构,因此我受到该设计的限制。您是否尝试将实体状态设置为删除
foreach(item.Items中的var childitem)dbContext.Entry(childitem.State=EntityState.Deleted?这就是问题所在,项目。项目不包含我要删除的项目,它只有新的项目B,该项目已添加,原始项目B处于孤立状态。我的意思是在删除和重新添加之前。但是你想用下面这行删除什么呢<代码>item.Items.Remove(item.Items.FirstOrDefault(x=>(int)x.Type==model.Type))您从何处获取项目?从数据库?我不想触及我的控制器方法中的上下文(调用该方法的地方)。我打算在某个时候从UI层完全抽象EF实体。代码的目的是删除类型匹配的任何记录(和子记录),基本上意味着您只能拥有该类型中的一个。这是对现有数据库的重构,因此我受到该设计的限制。