【问题标题】:Entity Framework seeding causes insert statement conflict with foreign key实体框架播种导致插入语句与外键冲突
【发布时间】:2015-01-05 11:42:33
【问题描述】:

我有一个简单的模型:

class Employee {
 int EmployeeId {get;set;}
 List<Task> Tasks {get;set;}
}

class Manager {
 int ManagerId {get;set;}
 List<Task> Tasks {get;set;}
}

class Task {
 int TaskId {get;set;}
 EmployeeId {get;set;}
 ManagerId {get;set;}

 [ForeignKey("EmployeeId")]
 Employee Employee {get;set;}

 [ForeignKey("ManagerId")]
 Manager Manager {get;set;}
}

class Task1 : Task { }
class Task2 : Task { }

当我尝试为数据库播种时出现异常,这就是我播种的方式:

Employee employee = new Employee();
context.Employees.Add(employee);
context.SaveChanges();

Manager manager = new Manager();
context.Managers.Add(manager);
context.SaveChanges();

List<Task> EmpTask = new List<Task>();
//EXCEPTION OCCURS HERE WHEN I TRY TO ADD NEW TASK ITEMS 
Task EmpOne = new Task1();
Task EmpTwo = new Task2();
EmpTask.Add(EmpOne);
EmpTask.Add(EmpTwo);

Employee.Tasks = EmpTask;
Context.Entry(employee).State = EntityState.Modified;
Context.SaveChanges();

List<Task> ManagerTask = new List<Task>();
Task ManagerOne = new Task1();
Task ManagerTwo = new Task2();
ManagerTask.Add(ManagerOne);
ManagerTask.Add(ManagerTwo);

Manager.Tasks = ManagerTask;
Context.Entry(manager).State = EntityState.Modified;
Context.SaveChanges();

我不断得到的例外是:

{"INSERT 语句与 FOREIGN KEY 约束 \"FK_dbo.Task_dbo.Employee_EmployeeId\" 冲突。冲突发生在数据库 \"GIP\",表 \"dbo.Employee\",列 'EmployeeId'。\ r\n语句已终止。"}

但是,当我将代码更改为以下代码时,我没有任何问题(以相同的方式播种,但没有管理器部分):

class Employee {
 int EmployeeId {get;set;}
 List<Task> Tasks {get;set;}
}
class Task {
 int TaskId {get;set;}
 int EmployeeId {get;set;}
 [ForeignKey("EmployeeId")]
 Employee Employee {get;set;}
}

似乎当 Task 类有 2 个外键约束时,它会变得混乱或什么......

另外,如果我重新添加 Manager 类,但从 Task 类中删除所有 ForeignKey 约束,它没有问题,因为它在数据库中创建了自己的自动生成的外键列,其中一些员工外键为 Null经理任务,并且员工任务的经理外键为空

【问题讨论】:

  • 这是您的实际代码吗?
  • 它的一部分,它与其他部分(其他模型/实体/类)有点长,但这是相关部分,我将更新我的问题以添加可能的附加信息提供更多上下文
  • 您似乎遗漏了 EmployeeId 和 ManagerId 的类型。他们是整数吗?试试 Nullable.
  • 不完全确定您的问题,但我注意到了一些事情。当您首先编写代码时,通常不会放置外键列。您的任务具有员工和经理类的属性,这就是 EF 在数据库中构建正确密钥所需的全部内容。此外,当您添加数据时,您无需在每次插入内容时调用保存更改。这不像使用 SQL 将数据添加到数据库中。建立所有 EF 对象关系并在最后调用一次保存更改。
  • @Kirby 我明白了,谢谢你的澄清,不过我有一个问题。如果我需要访问数据库中的外键会怎样?我自己放置外键列的原因是因为我有一个 post 方法,我需要将任务对象插入到正确的员工或经理中,但员工和经理实际上是我完整项目中另一个类中的列表,所以我可以拥有多名员工和多名经理

标签: c# mysql asp.net-mvc entity-framework asp.net-mvc-5


【解决方案1】:

确保您的 FK 列可以为空,例如。 int? 而不是 int。如果它们不为null,则默认为0,这将引用具有0键的实体,这将违反FK约束。

【讨论】:

    【解决方案2】:

    如果您要指定自己的外键,则属性必须是虚拟的。

    例子:

    [外键(“员工”)] 公共虚拟 int EmployeeId { 获取;放; }

    [ForeignKey("EmployeeId")] 公共虚拟雇员雇员{得到;放; }

    【讨论】:

    • 我会试试这个,我想我之前做过这个但没用,不过再试一次
    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 2018-04-25
    • 1970-01-01
    • 2015-05-17
    相关资源
    最近更新 更多