c# - Entity Framework 4.1 Codefirst : "Given multiplicity constraints" error when deleting one-to-many children

标签 c# entity-framework-4 one-to-many

我在 Entity Framework 4.1 中有以下类(这些类已被修剪以保持代码可读性)

public class MetaInformation
{
    public int Id { get; set; }
    public virtual MetaInformationObject RelatedTo { get; set; }
}

public abstract class MetaInformationObject
{
    public int Id { get; set; }
    public virtual List<MetaInformation> MetaInformations { get; set; }
}

[Table("Hardwares")]
public class Hardware : MetaInformationObject
{
    [MaxLength(100)]
    public string Name { get; set; }
}

public class Inventory
{
    public int Id { get; set; }
    public virtual List<Machine> Machines { get; set; }
}

public class Machine : Hardware
{
    public Inventory Inventory { get; set; }
}

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Isis.Business.Base.MetaInformationObject>()
        .HasMany<Isis.Business.Base.MetaInformation>(mi => mi.MetaInformations).WithRequired(mi => mi.RelatedTo).WillCascadeOnDelete(true);
    modelBuilder.Entity<Isis.Business.Inventory.Inventory>()
            .HasMany<Isis.Business.Inventory.Machine>(i => i.Machines).WithRequired(m => m.Inventory).WillCascadeOnDelete(true);

    base.OnModelCreating(modelBuilder);
}

有一次,我想更新机器信息,所以如果它已经存在于数据库中,我加载它,附加它,然后清除以前的元信息以用新的元信息替换它们。

public void UpdateMachine(Inventory i, Machine m)
{
    DataContext.Dao.Db.Inventories.Attach(i);
    if (!i.Machines.Exists(InnerHardware => InnerHardware.SerialNumber == m.SerialNumber)) {
        i.Machines.Add(m);
    } else {
        var workingMachine = i.Machines.First(Machine => Machine.SerialNumber == m.SerialNumber);
        Dao.Db.Machines.Attach(workingMachine);
        if (workingMachine.MetaInformations != null && workingMachine.MetaInformations.Count > 0) {
            workingMachine.MetaInformations.Clear();
            //workingMachine.MetaInformations.ForEach(mi => { Dao.Db.MetaInformations.Attach(mi); Dao.Db.MetaInformations.Remove(mi); }); // tried this to, with variations
        }
        workingMachine.MetaInformations = m.MetaInformations;
    }
    DataContext.Dao.Db.SaveChanges();
}

然后,抛出以下 DbUpdateException:

A relationship from the 'MetaInformationObject_MetaInformations' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'MetaInformationObject_MetaInformations_Target' must also in the 'Deleted' state.

我尝试在 SO 上关注一些问题来解决问题,尤其是尝试阅读 this onethe link在答案中提供(这就是为什么从 MetaInformation 直接引用到 MetaInformationObject 的原因)但我无法弄清楚哪里出了问题。

最佳答案

级联删除在这里帮不了你。级联删除仅在删除父实体 (MetaInformationObject) 时有效。这里的问题是对相关对象的集合调用 Clear 不会删除它们。它只会删除关系(= 它将 MetaInformation 中的外键设置为 null)但您的映射约束不允许这样做(您根据需要定义了关系)。避免这种情况的方法是:

  • 遍历所有相关的MetaInformation并删除它们中的每一个
  • 重构您的模型以定义 identifying relation .之后 Clear 不仅会破坏关系,还会将相关实体标记为已删除。

关于c# - Entity Framework 4.1 Codefirst : "Given multiplicity constraints" error when deleting one-to-many children,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6869874/

相关文章:

c# - 在事务中截断 Oracle 临时表,截断 *所有* 临时表

c# - EF4 将 DynamicProxies 转换为基础对象

sql-server - 数据库第一个 Entity Framework 更新模型不起作用: What can be the reason?

ruby-on-rails - rails : One-to-many foreign key incorrect

symfony - 错误 : Class . ..\Entity\.. 没有名为的关联

jpa - Spring Data 与集成测试 OneToMany ManyToOne

c# - 1对1关系EF两个外键报错

c# - 在派生类中转换接口(interface)属性

c# - 这两者之间有区别吗?

asp.net - 在应用程序配置中找不到 "The connection name ' LocalSqlServer'或连接字符串为空的方法。”错误?