INSERT语句与FOREIGN KEY约束冲突

时间:2016-12-31 07:36:09

标签: entity-framework ef-code-first

我对Entity Framework很新(代号优先)。这是我的两个实体 -

public class Employee
{
    public Employee() { }

    public long Id {get; set;}
    public string Fullname {get; set;}

    public virtual ICollection<Attendance> Attendances { get; set; }
}


public class Attendance
{
    public Attendance() { }
    public DateTime CheckinDateTime { get; set; }
    public DateTime? CheckoutDateTime { get; set; }

    public long EmployeeId { get; set; }

    [ForeignKey("Id")]
    public virtual Employee Employee{ get; set; }
}

员工与出勤有一对多的关系。

我试图创建一个新的出勤数据 -

var attendance = new Attendance() 
                   { EmployeeId = 1, 
                     CheckinDateTime = today.CurrentDateTime 
                   };
DbContext.Attendances.Add(attendance);
DbContext.SaveChanges(); //Exception here.

我在数据库中有一条员工记录。

为什么我得到例外?

1 个答案:

答案 0 :(得分:1)

  

Code First使您可以使用C#或Visual Basic .NET类来描述模型。使用约定检测模型的基本形状。约定是一组规则,用于在使用Code First时基于类定义自动配置概念模型。约定在System.Data.Entity.ModelConfiguration.Conventions命名空间中定义。   您可以使用数据注释或流畅的API进一步配置模型。优先通过流畅的API进行配置,然后是数据注释,然后是约定。有关更多信息,请参阅数据注释,Fluent API - 关系,Fluent API - 类型和&amp;使用VB.NET的属性和Fluent API。

您可以在此处找到有关Entity Framework Code First Conventions

的更多信息

您将错误的ID名称设置为FK和PK,您还需要为Attendance添加主键,请按照代码的第一个约定名称,更改您的模型,如:

public class Employee
{
    public Employee()
    {
        Attendances = new List<Attendance>();
    }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long EmployeeId { get; set; }
    public string Fullname { get; set; }

    public virtual ICollection<Attendance> Attendances { get; set; }
}


public class Attendance
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long AttendanceId { get; set; }
    public DateTime CheckinDateTime { get; set; }
    public DateTime? CheckoutDateTime { get; set; }
    [Required]
    [ForeignKey("Employee")]
    public long EmployeeId { get; set; }

    public virtual Employee Employee { get; set; }
}

ForeignKey属性应用于Attendance navigation属性,以指定Attendance属性的foreignkey属性名称。

如果没有DataAnnotation,我们可以使用Fluent API来配置我们的关系。当然,您需要使用代码第一个约定名称

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //one-to-many 
    modelBuilder.Entity<Attendance>()
                .HasRequired<Employee>(e => e.Employee) // Attendance entity requires Employee 
                .WithMany(a => a.Attendances); // Employee entity includes many Attendances entities

}

如果您的模型不包含约定名称,则使用Fluent API可以使用.HasForeignKey()并设置特定名称FK

public class Attendance
{

    public long AttendanceId { get; set; }
    public DateTime CheckinDateTime { get; set; }
    public DateTime? CheckoutDateTime { get; set; }

    //Not first code convention name
    public long EmpId { get; set; }

    public virtual Employee Employee { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //one-to-many 
    modelBuilder.Entity<Attendance>()
                .HasRequired<Employee>(e => e.Employee)
                .WithMany(a => a.Attendances)
                .HasForeignKey(e => e.EmpId);
}