0

我有以下两个代表 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");
}

我认为调用此操作方法时会引发异常,因为Deptwithid=1已经有一个 id=100 的emp。但是发生的事情是EF首先删除了emp,然后是dept。作为上述操作方法的最终结果,删除了 id=1 的部门和 id =100 的 emp .. 请您对此提出建议吗?请记住,如果我尝试仅按以下方式删除 Dept:

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");
}

我会得到以下异常: -

DELETE 语句与 REFERENCE 约束 \"FK_Emp_ToTable\" 冲突。冲突发生在数据库 \"C:\USERS\...\DOCUMENTS\VISUAL STUDIO 2013\PROJECTS\WEBAPPLICATION19\WEBAPPLICATION19\APP_DATA\DATABASE1.MDF\",表 \"dbo.Emp\",列 'DeptID' 中。 \r\n语句已终止。"}

那么任何人都可以就 EF 如何实现这些场景提出建议吗?

编辑

我检查了我的操作方法的 sql 探查器,我注意到以下 2 个删除 sql 语句:-

exec sp_executesql N'delete [dbo].[Emp]
where ([EmpID] = @0)',N'@0 int',@0=100

exec sp_executesql N'delete [dbo].[Dept]
where ([DeptID] = @0)',N'@0 int',@0=1

所以它先删除了emp,然后删除了dept,那么EF如何确定顺序,你提到它足够聪明,但是什么支配了这种行为?

4

1 回答 1

1

您试图删除一个分配给它Dept的集合。Emp

发生以下异常

DELETE 语句与 REFERENCE 约束冲突

这意味着 Dept - Emp 关系存在约束。我的猜测是这是一对多的关系,其中一个部门对 Emp 来说是可选的。

我可以说它是可选的,因为外键DeptIDNullable<int>.

当您尝试删除 aDept时,您会得到一个异常,因为在 .dept 中引用了 dept Emp

在您通过主键删除的第一个操作方法中

    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.

在你的情况下,我看到两个SQL Delete statements被称为关系是为了识别

当主体实体的主键也是从属实体的主键的一部分时,该关系是识别关系。在识别关系中,从属实体不能在没有主体实体的情况下存在。此约束导致识别关系中的以下行为:

删除主体对象也会删除从属对象。这与在模型中为关系指定的行为相同。

删除关系会删除依赖对象。对 EntityCollection 调用 Remove 方法将关系和依赖对象都标记为删除。

于 2014-12-21T12:49:16.450 回答