C# 将现有的代码优先模型和fluent aPI配置从Entity Framework 6移植到Entity Framework Core 2.0

C# 将现有的代码优先模型和fluent aPI配置从Entity Framework 6移植到Entity Framework Core 2.0,c#,.net,entity-framework-6,ef-code-first,ef-core-2.0,C#,.net,Entity Framework 6,Ef Code First,Ef Core 2.0,假设在使用Ef 6的应用程序中,我有以下模型和fluentapi配置,它们定义了车主和他拥有的汽车之间的关系。汽车与车主的关系为1:0或1,而车主与汽车的关系为1:0或多 public class Car { public int Id { get; set; } public string ChasisNumber { get; set; } public string EngineNumber { get; set; } public CarOwner Ca

假设在使用Ef 6的应用程序中,我有以下模型和fluentapi配置,它们定义了车主和他拥有的汽车之间的关系。汽车与车主的关系为1:0或1,而车主与汽车的关系为1:0或多

public class Car
{
    public int Id { get; set; }
    public string ChasisNumber { get; set; }
    public string EngineNumber { get; set; }

    public CarOwner CarOwner { get; set; }
}

public class CarOwner
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public IList<Car> Cars {get; set;}
}
有什么方法可以防止将CarOwnerId添加为Car实体中的参考密钥?我想确保我的模型与实体框架6中的模型保持一致。我不想对我的模型做任何改变。我更愿意在fluent api配置文件中进行所有必要的更改

在EF Core 2.0中,由于需要将模型中的车主外键指定为可为空的整数属性,因此汽车模型会发生变化

绝对没有必要这样做。事实上,EF Core为您提供了更多的控制权。只是默认的FK名称约定不同,所以为了保留EF6名称,必须使用fluent API显式配置它们

以下是原始车型的等效EF核心配置(车内不带
public int?CarOwnerId{get;set;}
):

公共类CarConfiguration:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder)
{
HasKey(a=>a.Id);
builder.Property(a=>a.Id).ValueGeneratedOnAdd().IsRequired();
builder.HasOne(x=>x.CarOwner)
.有很多(x=>x辆车)
.HasForeignKey(“车主Id”)//a.Id);
builder.Property(a=>a.Id).ValueGeneratedOnAdd().IsRequired();
}
}
请注意,大多数fluent配置都是冗余的,可以省略,因为它们是EF常规默认设置。此外,关系配置应位于一个位置,以避免设置冲突-关系始终有两个端点,因此从逻辑上讲,它不是两个实体中任何一个的一部分(不适合实体类型配置分离)

实现相同映射的最小fluent配置如下(根本不使用实体类型配置):

modelBuilder.Entity()
.HasOne(x=>x.CarOwner)
.有很多(x=>x辆车)
.HasForeignKey(“车主身份证”);

感谢您抽出时间回答。你的回答很有帮助
public class CarConfiguration : EntityTypeConfiguration<Car>
{
    HasKey(a => a.Id);
    Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
    HasOptional(x => x.CarOwner).WithMany(x => x.Cars).Map(x => x.MapKey("CarOwner_Id"));
}

public class CarOwnerConfiguration : EntityTypeConfiguration<CarOwner>
{
    HasKey(a => a.Id);
    Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
    HasMany(a => a.Cars).WithOptional(a => a.CarOwner);
}
public class Car
{
    public int Id { get; set; }
    public string ChasisNumber { get; set; }
    public string EngineNumber { get; set; }

    public int? CarOwnerId { get;set; }
    public CarOwner CarOwner { get; set; }
}
public class CarConfiguration : IEntityTypeConfiguration<Car>
{
    public void Configure(EntityTypeBuilder<Car> builder)
    {
        builder.HasKey(a => a.Id);
        builder.Property(a => a.Id).ValueGeneratedOnAdd().IsRequired();
        builder.HasOne(x => x.CarOwner)
            .WithMany(x => x.Cars)
            .HasForeignKey("CarOwner_Id") // <--
            .IsRequired(false);
    }
}

public class CarOwnerConfiguration : IEntityTypeConfiguration<CarOwner>
{
    public void Configure(EntityTypeBuilder<CarOwner> builder)
    {
        builder.HasKey(a => a.Id);
        builder.Property(a => a.Id).ValueGeneratedOnAdd().IsRequired();
    }
}
modelBuilder.Entity<Car>()
    .HasOne(x => x.CarOwner)
    .WithMany(x => x.Cars)
    .HasForeignKey("CarOwner_Id");