删除可选的1对多不会将外键设置为空

时间:2015-07-20 23:50:52

标签: c# sql-server entity-framework ef-code-first

我有两个实体,它们定义并配置了可选的1对多关系:

public class A 
{
   // ...
   public int? BId { get; set; }
   public B B { get; set; }
}

public class B 
{
   // ...
   public virtual ICollection<A> As { get; set; }
}


public class AConfiguration : EntityTypeConfiguration<A>
{
     public A() 
     {
         // ...
         HasOptional(r => r.B).WithMany(r => r.As).HasForeignKey(r => r.BId);
     }
}

当在类型B的实体上删除时,我希望删除具有到B实体的外键的类型A的所有实体将该BId外键设置为null。因此定义了删除操作:

public void DeleteB(int bId)
{
    var entity = _context.Bs.Single(b => b.Id == bId);
    _context.Bs.Remove(entity);
    _context.SaveChanges();
}

然而,会发生。 B类实体已成功删除,但A实体上的BId仍为非null,而对.SaveChanges()的任何其他调用都会抛出异常,因为这些BId引用的行不再存在。

如何以一种使BId属性无效的方式删除B实体,而不必在删除操作期间手动迭代该集合?

1 个答案:

答案 0 :(得分:1)

如果当前关联的实体已加载到上下文中,则外键仅会自动设置为null。换句话说,当删除b时,如果类型为A的实体已加载,则BId类型的关联集合只会将其A属性设置为null进入上下文。否则,EF将不知道它们的存在(除非EF提供程序自动生成SQL,将这些外键设置为null ...在SQL Server的情况下不会这样做。)

一种选择是这样做(如果你不介意加载所有这些实体):

public void DeleteB(int bId)
{
    var entity = _context.Bs.Single(b => b.Id == bId);
    _context.Entry(entity).Collection(b => b.As).Load(); 
    _context.Bs.Remove(entity);
    _context.SaveChanges();
}

另一种选择是编写自己的SQL语句并运行它。