【问题标题】:Foreign Key help in Entity Framework Codefirst实体框架代码优先中的外键帮助
【发布时间】:2012-12-04 14:55:49
【问题描述】:

我有两个模型类:出勤和员工。我已将 Employee 类定义为:

public class Employee
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}

然后我将出勤类定义为:

public class Attendance
{
    public int Id { get; set; }
    public Employee Employee { get; set; } //This is the foreign key
    public DateTime LoginDate { get; set; }
    public DateTime LogoutDate { get; set; }
}

当我尝试将数据插入 Employee 表时,它工作正常,但是当我尝试在出勤表中插入数据时,它显示异常。我正在正确检查员工并在出勤表中仅插入一行员工。

这是异常的图像:

【问题讨论】:

  • 什么是内部异常(根据主要异常的说明)。另外,您如何创建和保存出勤对象? (显示示例)。

标签: c# .net entity-framework ef-code-first


【解决方案1】:

为了解决您看到的错误(并获取有关根本问题的更多详细信息),将 EmployeeId 的字段添加到出勤类,如下所示

public class Attendance
{
    public int Id { get; set; }
    //This exposes the foreign key on attendance
    public int EmployeeId {get; set;}
    public Employee Employee { get; set; } //This is the foreign key
    public DateTime LoginDate { get; set; }
    public DateTime LogoutDate { get; set; }
}

真正的问题(我相信)是 EF 无法确定关系的所有者。如果没有更多信息,则无法确定出勤与员工的关系是多对一还是一对一。一个简单的解决方案(我假设它是多对一的关系)是像这样向 Employee 类添加一个出勤对象的集合

public class Employee
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public virtual ICollection<Attendance> Attendances {get; protected set;}
}

【讨论】:

  • 我不是 EF 专家,但考勤收集不需要是虚拟的吗?
  • 好的,我会试试这个,但这是一个简单的一对一关系。如果是一对一怎么办?
  • 出席不需要是虚拟的,有关虚拟和 EF stackoverflow.com/a/7738919/637425 的更多信息,请参阅此 SO 答案
  • 如果您使用延迟加载(我相信这是 EF 的默认设置),它确实需要是虚拟的。否则,你是对的,没有它也能正常工作。
【解决方案2】:

你需要定义一个外键属性:

public class Attendance
{
    public int Id { get; set; }
    public int EmployeeID { get; set; }
    public Employee Employee { get; set; }
    public DateTime LoginDate { get; set; }
    public DateTime LogoutDate { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}

将外键添加为int后,您可以对其进行配置:

public class AttendanceConfiguration : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Attendance>
{
    public AttendanceConfiguration()
    {
        this.HasRequired(a => a.Employee)
            .WithMany()
            .HasForeignKey(a => a.EmployeeID);
    }
}

然后在上下文中定义这个配置

public class Context : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new AttendanceConfiguration());
    }
}

更新
通过使用没有参数的 WithMany() 重载,您可以建立一个单向的一对多关系。

【讨论】:

    【解决方案3】:

    您需要公开密钥本身,而不仅仅是实体。

    public class Attendance
    {
        public int Id { get; set; }
        public Employee Employee { get; set; }
        public int EmployeeId { get; set; } // THIS is the foreign key.
        public DateTime LoginDate { get; set; }
        public DateTime LogoutDate { get; set; }
    }
    

    【讨论】:

      【解决方案4】:

      尝试在您的员工实体上放置一个关键属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 2012-05-10
        • 2015-02-24
        • 2021-01-05
        • 2011-08-05
        相关资源
        最近更新 更多