C# 添加外键时,EF核心代码中首先生成的双id字段
我正在开发一个跟踪客户汽车的应用程序。我首先使用EF核心代码。这就是我对两个表(车辆和牌照)的问题所在 一辆车可以有多个牌照(但一次只能有一个有效牌照),一个牌照可以属于一辆车。到目前为止,一切都很顺利,但对于一个新功能,我想实现汽车牌照的历史记录。为此,我在vehicle类中添加了一个activeLicensePlate字段,它应该包含licensePlate(id字段)表的外键 我的守则如下: 车辆等级(添加新代码前): 模型约束:C# 添加外键时,EF核心代码中首先生成的双id字段,c#,mysql,entity-framework,asp.net-core,entity-framework-core,C#,Mysql,Entity Framework,Asp.net Core,Entity Framework Core,我正在开发一个跟踪客户汽车的应用程序。我首先使用EF核心代码。这就是我对两个表(车辆和牌照)的问题所在 一辆车可以有多个牌照(但一次只能有一个有效牌照),一个牌照可以属于一辆车。到目前为止,一切都很顺利,但对于一个新功能,我想实现汽车牌照的历史记录。为此,我在vehicle类中添加了一个activeLicensePlate字段,它应该包含licensePlate(id字段)表的外键 我的守则如下: 车辆等级(添加新代码前): 模型约束: //rel vehicle license plate
//rel vehicle license plate one many
modelBuilder.Entity<LicensePlate>()
.HasOne<Vehicle>(l => l.Vehicle)
.WithMany(v => v.LicensePlates)
.HasForeignKey(l => l.VehicleId)
.IsRequired();
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class VehicleModelConstraints
{
public static void OnModelCreatingVehicle(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Vehicle>()
.HasKey(v => v.Id);
modelBuilder.Entity<Vehicle>()
.Property(v => v.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Vehicle>()
.Property(v => v.FuelType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.VehicleType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.Mileage)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ChassisNr)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ActiveLicensePlateId)
.IsRequired();
}
}
}
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class LicensePlateModelConstraints
{
public static void OnModelCreatingLicensePlate(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicensePlate>()
.HasKey(l => l.Id);
modelBuilder.Entity<LicensePlate>()
.Property(l => l.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<LicensePlate>()
.Property(l => l.LicensePlateCharacters)
.IsRequired();
}
}
}
//rel车辆牌照一张多张
modelBuilder.Entity()
.HasOne(l=>l.Vehicle)
.有许多(v=>v.牌照)
.HasForeignKey(l=>l.VehicleId)
.IsRequired();
车辆模型约束:
//rel vehicle license plate one many
modelBuilder.Entity<LicensePlate>()
.HasOne<Vehicle>(l => l.Vehicle)
.WithMany(v => v.LicensePlates)
.HasForeignKey(l => l.VehicleId)
.IsRequired();
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class VehicleModelConstraints
{
public static void OnModelCreatingVehicle(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Vehicle>()
.HasKey(v => v.Id);
modelBuilder.Entity<Vehicle>()
.Property(v => v.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Vehicle>()
.Property(v => v.FuelType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.VehicleType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.Mileage)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ChassisNr)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ActiveLicensePlateId)
.IsRequired();
}
}
}
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class LicensePlateModelConstraints
{
public static void OnModelCreatingLicensePlate(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicensePlate>()
.HasKey(l => l.Id);
modelBuilder.Entity<LicensePlate>()
.Property(l => l.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<LicensePlate>()
.Property(l => l.LicensePlateCharacters)
.IsRequired();
}
}
}
使用Microsoft.EntityFrameworkCore;
使用模型;
名称空间ReadRepositories.Mappings
{
公共静态类车辆模型约束
{
ModelCreatingVehicle上的公共静态无效(此ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(v=>v.Id);
modelBuilder.Entity()
.Property(v=>v.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity()
.Property(v=>v.FuelType)
.IsRequired();
modelBuilder.Entity()
.Property(v=>v.VehicleType)
.IsRequired();
modelBuilder.Entity()
.属性(v=>v.里程)
.IsRequired();
modelBuilder.Entity()
.Property(v=>v.ChassisNr)
.IsRequired();
modelBuilder.Entity()
.Property(v=>v.ActiveLicensePlateId)
.IsRequired();
}
}
}
车牌模型约束:
//rel vehicle license plate one many
modelBuilder.Entity<LicensePlate>()
.HasOne<Vehicle>(l => l.Vehicle)
.WithMany(v => v.LicensePlates)
.HasForeignKey(l => l.VehicleId)
.IsRequired();
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class VehicleModelConstraints
{
public static void OnModelCreatingVehicle(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Vehicle>()
.HasKey(v => v.Id);
modelBuilder.Entity<Vehicle>()
.Property(v => v.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Vehicle>()
.Property(v => v.FuelType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.VehicleType)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.Mileage)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ChassisNr)
.IsRequired();
modelBuilder.Entity<Vehicle>()
.Property(v => v.ActiveLicensePlateId)
.IsRequired();
}
}
}
using Microsoft.EntityFrameworkCore;
using Models;
namespace ReadRepositories.Mappings
{
public static class LicensePlateModelConstraints
{
public static void OnModelCreatingLicensePlate(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicensePlate>()
.HasKey(l => l.Id);
modelBuilder.Entity<LicensePlate>()
.Property(l => l.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<LicensePlate>()
.Property(l => l.LicensePlateCharacters)
.IsRequired();
}
}
}
使用Microsoft.EntityFrameworkCore;
使用模型;
名称空间ReadRepositories.Mappings
{
公共静态类许可证模板约束
{
ModelCreatingLicensePlate上的公共静态无效(此ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(l=>l.Id);
modelBuilder.Entity()
.Property(l=>l.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity()
.Property(l=>l.LicensePlateCharacters)
.IsRequired();
}
}
}
生成的迁移:
using Microsoft.EntityFrameworkCore.Migrations;
namespace Repositories.Migrations
{
public partial class ActiveLicensePlate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<long>(
name: "ActiveLicensePlateId",
table: "Vehicle",
type: "bigint",
nullable: false,
defaultValue: 0L);
migrationBuilder.AddColumn<long>(
name: "ActiveLicensePlateId1",
table: "Vehicle",
type: "bigint",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Vehicle_ActiveLicensePlateId1",
table: "Vehicle",
column: "ActiveLicensePlateId1");
migrationBuilder.AddForeignKey(
name: "FK_Vehicle_LicensePlate_ActiveLicensePlateId1",
table: "Vehicle",
column: "ActiveLicensePlateId1",
principalTable: "LicensePlate",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Vehicle_LicensePlate_ActiveLicensePlateId1",
table: "Vehicle");
migrationBuilder.DropIndex(
name: "IX_Vehicle_ActiveLicensePlateId1",
table: "Vehicle");
migrationBuilder.DropColumn(
name: "ActiveLicensePlateId",
table: "Vehicle");
migrationBuilder.DropColumn(
name: "ActiveLicensePlateId1",
table: "Vehicle");
}
}
}
使用Microsoft.EntityFrameworkCore.Migrations;
命名空间存储库.迁移
{
公共部分类ActiveLicensePlate:迁移
{
受保护的覆盖作废(MigrationBuilder MigrationBuilder)
{
migrationBuilder.AddColumn(
名称:“ActiveLicensePlateId”,
表:“车辆”,
键入:“bigint”,
可为空:false,
默认值:0升);
migrationBuilder.AddColumn(
名称:“ActiveLicensePlateId1”,
表:“车辆”,
键入:“bigint”,
可为空:真);
migrationBuilder.CreateIndex(
名称:“IX_车辆\u活动许可证平台ID1”,
表:“车辆”,
列:“ActiveLicensePlateId1”);
migrationBuilder.AddForeignKey(
名称:“FK_车辆\u许可证牌\u活动许可证牌ID1”,
表:“车辆”,
列:“ActiveLicensePlateId1”,
原则性:“许可证牌”,
主栏:“Id”,
onDelete:referentialiction.Restrict);
}
受保护的覆盖无效关闭(MigrationBuilder MigrationBuilder)
{
migrationBuilder.DropForeignKey(
名称:“FK_车辆\u许可证牌\u活动许可证牌ID1”,
表:“车辆”);
migrationBuilder.DropIndex(
名称:“IX_车辆\u活动许可证平台ID1”,
表:“车辆”);
migrationBuilder.DropColumn(
名称:“ActiveLicensePlateId”,
表:“车辆”);
migrationBuilder.DropColumn(
名称:“ActiveLicensePlateId1”,
表:“车辆”);
}
}
}
正如您在生成的迁移中所看到的,创建了一个名为ActiveLicensePlateId的字段,但也创建了一个名为ActiveLicensePlateId的字段(其中包含我要添加的外键)
迁移前我的数据库表:
车辆表:
车牌表:
因此,简单地说,我只想在vehicle表中添加一个字段,一个名为activeLicensePlate的字段。此字段应引用车牌的id,并使用车牌表的外键
有人知道出了什么问题吗?我不确定,但我认为您的显式属性定义使ef core忽略了您的外键,因为您没有标记它,所以删除它应该可以,因为您已经遵循了命名约定
//remove this
modelBuilder.Entity<Vehicle>()
.Property(v => v.ActiveLicensePlateId)
.IsRequired();
//删除此
modelBuilder.Entity()
.Property(v=>v.ActiveLicensePlateId)
.IsRequired();
或者更好的方法是使用fluentapi来定义关系
modelBuilder.Entity<Vehicle>()
.HasOne(p => p.ActiveLicensePlate)
.WithOne()
.HasForeignKey(p => p.ActiveLicensePlateId);
modelBuilder.Entity()
.HasOne(p=>p.ActiveLicensePlate)
.WithOne()
.HasForeignKey(p=>p.ActiveLicensePlateId);