实体框架 6.1:未在数据库中定义相应键的代码优先导航属性

本文关键字:代码 属性 导航 定义 框架 数据库 实体 | 更新日期: 2023-09-27 18:30:58

我正在尝试使用 EF 6.1 使用代码优先方法(我对它很陌生),并且我在数据库中基于 1.1 或 1.0 关系的导航属性方面遇到了一个奇怪的问题。

我有一个映射到用户表的用户类,如下所示:

[Table("TL_MF_SEC_USER_MST")]
public class User
{
    /// <summary>
    /// Table Column : USER_ID
    /// </summary>
    [Key, Column("USER_ID")]
    public decimal ID { get; set; }
    /// <summary>
    /// Table Column : USER_CODE
    /// </summary>
    [Column("USER_CODE")]
    public string Code { get; set; }
    /// <summary>
    /// Table Column : DOMAIN_NM
    /// </summary>
    [Column("DOMAIN_NM")]
    public string Domain { get; set; }
    /// <summary>
    /// Table Column : EMPLOYEE_ID
    /// </summary>
    [Column("EMPLOYEE_ID")]
    public string EmployeeID { get; set; }

以及映射到 Employee 表的 Employee 类,如下所示:

[Table("TL_MF_EMPLOYEE_MST")]
public class Employee
{
    /// <summary>
    /// Table Column : EMPLOYEE_CODE
    /// </summary>
    [Key, Column("EMPLOYEE_CODE")]
    public string EmployeeID { get; set; }
    /// <summary>
    /// Table Column : EMPLOYEE_NAME
    /// </summary>
    [Column("EMPLOYEE_NAME")]
    public string EMPLOYEE_NAME { get; set; }
    public string Manager { get; set; }

问题是这些表之间的"键"是 User 类中的 EmployeeID 属性(不是主键),该属性映射到 Employee 类中的 EmployeeID 属性(在数据库中也不是主键或外键)。

因此,我正在尝试在用户到员工上创建一个导航属性,但我无法弄清楚如何告诉 EF 使用这两个非键字段作为与用户匹配的属性。

不幸的是,我所处的环境可能无法对实际数据库架构进行重大更改,因为此结构用于管理至少 8 个应用程序(其中一些有 20 多个实例)中的权限。不过,一些小的更改(如添加索引或约束)可能会起作用。

如果有办法通过属性或流畅的 API 来做到这一点,我将不胜感激。欢迎任何建议。

提前谢谢。

实体框架 6.1:未在数据库中定义相应键的代码优先导航属性

EF

仅接受与主键属性的关联。但它只查看模型中定义的主键。因此,由于 EmployeeID 上的 Key 属性,您可以在关联中使用它,如下所示:

public class User
{
    [Key, Column("USER_ID")]
    public decimal ID { get; set; }
    ...
    [Column("EMPLOYEE_ID")]
    public string EmployeeID { get; set; }
    public Employee Employee { get; set; } // You need this property
}

在上下文中对OnModelCreating的覆盖:

modelBuilder.Entity<User>()
            .HasRequired(u => u.Employee) // Or HasOptional
            .WithMany()
            .HasForeignKey(u => u.EmployeeId);

显然,在EmployeeID上看到这个Key属性,您确定EmployeeIDEmployee的候选键。必须绝对保证这一点才能正常工作。

很明显,您使用代码优先而不进行迁移。对于迁移,此映射当然会在数据库中创建一个主键EmployeeId