One to one mapping in EF Code First and bi-directional navigation properties

≯℡__Kan透↙ 提交于 2021-02-19 08:26:37

问题


I have been tasked with porting an old app to MVC 3, and want to use EF's code first to replicate its existing database schema. The current code base is littered with hard coded SQL commands, and so the model I come up with has to be "compatible" with what the current system expects. I know I could use EF's Database First to do this, but the existing schema is so simple that I see no reason not to use code first, as I want a solid foundation to build on as we migrate away from our old hard-coded database interactions.

What I need the POCOs to look like:

public class Owner
{
    [Key]
    public Guid Owner_Id { get; set; }

    // Properties
    public string ContactName { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }

    // Navigational properties
    public virtual ICollection<Plant> Plants { get; set; }
}

public class Plant
{
    [Key]
    public Guid Plant_Id { get; set; }

    // Properties
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }

    // Foreign Keys
    public Guid Owner_Id { get; set; }

    // Navigational properties
    public virtual Owner Owner { get; set; }
    public virtual License License { get; set; }
}

public class License
{
    [Key] public Guid License_Id { get; set; }

    // Properties
    public int Total { get; set; }
    public int Users { get; set; }
    public string Key { get; set; }

    // Foreign Keys
    public Guid Plant_Id { get; set; }

    // Navigational properties
    public virtual Plant Plant { get; set; }
}

It's giving me this error on attempting to create the context:

"Unable to determine the principal end of an association between the types 'License' and 'Plant'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations."

I realize that Plant should have a nullable FK reference to a License_Id, and that License shouldn't have a FK for Plant_Id. But these are the cards I have been dealt. Is what I'm trying to do possible in EF?


回答1:


public class Plant
{
    public Guid PlantID { get; set; }
    public virtual License License { get; set; }
} 

public class License
{
     // No need to have a PlantID foreign key since the foreign key.
     public Guid LicenseID { get; set; }
     public virtual Plant Plant { get; set; }
}

In fluent-api (in your context class):

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Plant>().HasOptional(p => p.License).WithRequired(l => l.Plant);  

The only downgrade is that you actually defined one to zero or one. (which can be handled in code. but still...) For more info about One-to-One relationship please check out Entity Framework Code First One to One Relationship




回答2:


try adding in License

// Foreign Keys
public Guid Plant_Id { get; set; }

// Navigational properties
[ForeignKey("Plant_Id")]
public virtual Plant Plant { get; set; }

to let it know that this is foreign key, same for the other foreign keys.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Plant>()
            .HasOptional(e => e.License)
            .WithOptionalPrincipal(e => e.Plant);

    }


来源:https://stackoverflow.com/questions/7840828/one-to-one-mapping-in-ef-code-first-and-bi-directional-navigation-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!