简体   繁体   中英

Entity Framework 6.1: Code First navigation properties that do not have corresponding keys defined in database

I am trying the Code First approach with EF 6.1 (I'm very new to it) and I have a weird issue with a navigation property based on a 1.1 or 1.0 relationship in the Database.

I have a User class mapped to a User table that looks like:

[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; }

And an Employee class mapped to an Employee table that looks like:

[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; }

The problem is that the "Keys" between these tables are the EmployeeID property (not a primary key) from the User class which maps to the EmployeeID property (which is also not a primary or foreign key in the DB) in the Employee class.

Thus, I am trying to create a navigation property on User to Employee but I cannot figure out how to tell EF to use these two non-key fields as the properties to match the user on.

Unfortunately, I am in an environment where I probably can't make significant changes to the actual database schema as this structure is used for administering permissions in at least 8 apps (some of which have 20 plus instances). Some small changes (like adding an index or constraint) might work though.

If there is a way to do this via attributes or fluent api, I would really appreciate a heads up. Any recommendations are welcome.

Thanks in advance.

EF only accepts associations to primary key properties. But it only looks at primary keys defined in the model. So, because of the Key attribute on EmployeeID , you can use it in associations, like so:

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
}

And in the context's override of OnModelCreating :

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

Apparently, seeing this Key attribute on EmployeeID , you are certain that EmployeeID is a candidate key to Employee . This must be absolutely guaranteed for this to work correctly.

It's clear that you use code-first without migrations. With migrations, this mapping would of course create a primary key EmployeeId in the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM