我有以下两个实体集代表Dept& EMP: -
public partial class Dept
{
public Dept()
{
this.Emps = new HashSet<Emp>();
}
public int DeptID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Emp> Emps { get; set; }
}
public partial class Emp
{
public int EmpID { get; set; }
public string Fname { get; set; }
public string Lname { get; set; }
public int DeptID { get; set; }
public virtual Dept Dept { get; set; }
}
现在我编写了这个测试操作方法,它将尝试删除一个分配了一个Emp的部门,如下所示: -
public ActionResult Test()
{
Dept d = db.Depts.SingleOrDefault(a=>a.id ==1);
Emp e = db.Emps.SingleOrDefault(a => a.id == 100);
db.Entry(d).State = EntityState.Deleted;
db.Emps.Remove(e);
db.SaveChanges();
return Content("done");
}
我认为在调用此操作方法时会引发异常,因为带有Dept
的{{1}}已经有一个id = 100的emp。但是发生的事情是,EF首先移除了emp,然后是部门。作为上述动作方法的最终结果,删除了id = 1的部门和id = 100的emp ..所以你能对此提出建议吗?请记住,如果我尝试删除部门只是如下:
id=1
我将得到以下异常: -
DELETE语句与REFERENCE约束冲突\&#34; FK_Emp_ToTable \&#34;。冲突发生在数据库\&#34; C:\ USERS \ ... \ DOCUMENTS \ VISUAL STUDIO 2013 \ PROJECTS \ WEBAPPLICATION19 \ WEBAPPLICATION19 \ APP_DATA \ DATABASE1.MDF \&#34;,table \&#34; dbo。 Emp \&#34;,列&#39; DeptID&#39;。\ r \ n该声明已被终止。&#34;}
那么有人可以就EF如何实施这些场景提出建议吗?
修改
我检查sql profiler的动作方法,我注意到以下2个删除sql的声明: -
public ActionResult Test()
{
Dept d = db.Depts.SingleOrDefault(a=>a.id ==1);
//Emp e = db.Emps.SingleOrDefault(a => a.id == 100);
db.Entry(d).State = EntityState.Deleted;
//db.Emps.Remove(e);
db.SaveChanges();
return Content("done");
}
所以它首先删除了emp然后删除了部门,所以EF如何确定订单,你提到它很聪明,但是知道这个行为是什么?
答案 0 :(得分:1)
您试图删除分配了Dept
集合的Emp
。
发生以下异常
DELETE语句与REFERENCE约束冲突
这意味着Dept-Emp关系存在约束。 我的猜测是,这是一对多的关系,其中一个部门是Emp的可选项。
我可以告诉它是可选的,因为外键DeptID
是Nullable<int>
。
当您尝试删除Dept
时,会出现异常,因为Emp
中会引用dept。
在您按主键删除的第一个操作方法
中 Dept d = db.Depts.SingleOrDefault(a=>a.id ==1);
Emp e = db.Emps.SingleOrDefault(a => a.id == 100);
然后使用db.Emps.Remove(e);
标记已删除之间的关系。
如果关系是可选的,则仅使用Emp
SQL Update.
设置为Null
在你的情况下,我看到两个SQL Delete statements
被调用
这种关系就是识别。
当主体实体的主键也是从属实体的主键的一部分时,该关系是识别关系。在识别关系中,没有主体实体,依赖实体不能存在。此约束会在标识关系中导致以下行为:
删除主体对象也会删除依赖对象。这与在模型中为关系指定的行为相同。
删除关系会删除依赖对象。在EntityCollection上调用Remove方法标记关系和要删除的依赖对象。