Entity Framework Core Configuration one to zero or

2019-08-31 23:20发布

问题:

In my .NET MVC project, I have my domain classes with one to one or zero relationship as:

public class Person
{
    public int Id { get; set; }

    public string FullName { get; set; }

    public Address Address { get; set; }
}

public class Address
{
    public string Address { get; set; }
    public string City { get; set; }

    public virtual Person Person { get; set; }
    [Key, ForeignKey("Person")]
    public int PID { get; set; }
}

This is using EF 6.x and the Address entity uses PID (which is foreign key) as its identity column. This code is automatically configured in EF 6.x without any explicit configuration.

Now, I am porting this solution to .NET Core 2.1. Here, the EF Core doesn't work with the Data Annotations of EF 6.x. I cannot for example get the property person.Address.City It appears I need to configure it manually using FluentAPI.

So far I have tried three different configs, one after another to no avail:

//First config
       modelBuilder.Entity<Person>()
            .HasOne(p => p.Address)
            .WithOne(a => a.Person);

//Second config
        modelBuilder.Entity<Person>()
            .OwnsOne(p => p.Address);

//Third config
        modelBuilder.Entity<Person>()
            .OwnsOne(p => p.Address)
            .OwnsOne(a=>a.Person);

This project has a lot of data and needs to be configured using the existing entity structure. Please help.

回答1:

Your first try was close, you just need to specify which field is the foreign key of the relationship using the HasForeignKey method:

modelBuilder.Entity<Person>()
    .HasOne(p => p.Address)
    .WithOne(a => a.Person)
    .HasForeignKey<Address>(a => a.PID);

And for the sake of completeness:

public class Address
{
    [Column("Address")]
    public string Addr { get; set; }
    public string City { get; set; }

    public virtual Person Person { get; set; }
    [Key]
    public int PID { get; set; }
}

You don't need the ForeignKey attribute on the PID property any more as this relationship is configured fluently. Furthermore, your code produced a compiler error because classes cannot have members of the same name. Hence I added a Column attribute to workaround this problem.