EF中的一对一关系

时间:2015-01-28 18:41:04

标签: database entity-framework entity-framework-6

我的模型看起来如下:

public class Job
{
    public int Id { get; set; }
    public virtual JobResult Result { get; set; }
}
public class JobResult
{
    [Key, ForeignKey("Job")]
    public int JobId { get; set; }
    [Required]
    public virtual Job Job { get; set; }
}

如您所见,这种关系是必需的一对一。 当我尝试创建并保存作业时:

Job job = new Job();
job.Result = new Result();
context.Jobs.add(job);
context.SaveChanges();

我收到以下错误:

  

无法确定相关操作的有效排序。   由于外键约束,模型可能存在依赖关系   要求或商店生成的值。

我不太明白错误信息。它是什么意思以及可能导致此错误的原因是什么?

2 个答案:

答案 0 :(得分:3)

您的案件无效,因为这是一份循环参考。必须做什么EF:

  1. 插入JobResults(....., Job_Id) VALUES (....., @JobId);
  2. EF无法执行此操作,因为未插入作业且没有ID。

    1. 插入Jobs(....., JobResult_Id) VALUES (....., @JobResultId);
    2. EF也不能这样做因为没有插入JobResult并且没有Id。 这是一个恶性循环。

      您可以修改模型。摆脱其中一个链接。例如:

      public class Job
      {
          public int Id { get; set; }
          public virtual JobResult Result { get; set; }
      }
      
      public class JobResult
      {
          public int Id { get; set; }
          public virtual Job Job { get; set; }
      }
      
      class JobResultConfiguration : EntityTypeConfiguration<JobResult>
      {
          public JobResultConfiguration()
          {
              HasRequired(e => e.Job).WithRequiredPrincipal(e => e.Result); // one-to-one
          }
      }
      
      public class MyContext : DbContext
      {
          protected override void OnModelCreating(DbModelBuilder modelBuilder)
          {
              modelBuilder.Configurations.Add(new JobResultConfiguration());
          }
      }
      

      这样你就可以:

      Job job = new Job();
      job.Result = new Result();
      context.Jobs.add(job);
      context.SaveChanges();
      

      EF建立一对一关系:两个实体,两个实体具有相同的主键。

      关于Fluent Api的更多细节:https://msdn.microsoft.com/en-us/data/jj591620.aspx

      或者你的地方修改了模型域名。当你循环链接时,我会试图摆脱一个链接(或来自Job或来自JobResult)

答案 1 :(得分:1)

您的[Required]字段位于您正在执行的操作类型的错误元素上。由于您需要JobResult拥有Job,因此您可以创建JobResult,然后创建从属Job(没有要求),但不是其他方式周围。如果您尝试从Job端创建Job,则JobResult不会附加到JobResult,直到创建它为止,但它无法创建,直到{{1}}是创建循环引用。