我在 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:
来自'MetaInformationObject_MetaInformations'的关系 AssociationSet处于“已删除”状态。鉴于多样性 约束,相应的 'MetaInformationObject_MetaInformations_Target'也必须在 '已删除'状态。
我尝试在此处提出一些问题来解决问题,特别是尝试阅读答案中提供的this one和the link(这就是MetaInformation
直接引用的原因到MetaInformationObject
)但我无法弄清楚出了什么问题。
答案 0 :(得分:16)
级联删除对您没有帮助。只有删除父实体(MetaInformationObject
)时才会进行级联删除。这里的问题是在相关对象的集合上调用Clear不会删除它们。它只删除关系(=它会将MetaInformation
中的外键设置为null)但是映射约束不允许(您根据需要定义了关系)。避免这种情况的方法是:
MetaInformation
并删除其中的每一个Clear
不仅会破坏关系,还会将相关实体标记为已删除。答案 1 :(得分:0)
回应以上评论,下面的代码可以解决您的问题
DataContext.Dao.Db.MetaInformations.RemoveRange(workingMachine.MetaInformations);