Bam*_*dad 16 sql-server entity-framework-core ef-core-5.0
有这两个实体:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public CompanyVehicle CompanyVehicle { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和
public class CompanyVehicle
{
public int Id { get; set; }
public string Name { get; set; }
public Employee Employee { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用Entity Framework Core 5.0.8
on SQL Server 2019
,CompanyVehicle 的配置为:
entityBuilder.HasOne(t => t.Employee)
.WithOne(t => t.CompanyVehicle)
.HasForeignKey<Employee>(t => t.Id)
.IsRequired();
Run Code Online (Sandbox Code Playgroud)
我们将尝试插入一些东西:
public void Create(Employee employee)
{
employee.CompanyVehicle = new CompanyVehicle();
dbContext.Add<Employee>(employee);
dbContext.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码曾经在EF6
. Employee 和 CompanyVehicle 表中的两条新记录都是使用相同的Id
. 迁移到 后EF Core 5.0.8
,dbContext.SaveChanges() 抛出异常:
System.InvalidOperationException:“尝试保存更改时,‘Employee.Id’的值未知。这是因为该属性也是外键的一部分,而关系中的主要实体是未知的。
请注意,这些实体只是示例,在我的例子中不应更改数据库设计。
更新
经过更多调查,我发现我的问题是:
将X
(主要)和Y
(依赖)作为两个表,其中X.Id
PK forX
和Y.Id
is PK forY
以及 FK to ,在 EF Core 中无法插入X
记录。X
所以我终于找到了问题所在,配置一个Property既是又PK
是FK
可以的,而且非常简单。在从程序集中迁移到EFCore
from后,我们有了旧代码。EF6
该项目是一个框架,因此我们在基础中OnModelCreating
使用它来注册来宾项目中的配置。项目将自动查找应用程序路径中项目引用的所有程序集或 DLL 中的所有配置。
关键点是:在显式流畅配置中,与. 所以在for中我们曾经这样写:modelBuilder.ApplyConfigurationsFromAssembly
DbContext
EF Core
FK
EF6
EF6
Employee
this.HasRequired(t => t.CompanyVehicle)
.WithRequiredDependent(t => t.Employee)
.HasForeignKey(d => d.Id);
Run Code Online (Sandbox Code Playgroud)
我们EF Core
应该写:
b.HasOne(t => t.CompanyVehicle)
.WithOne(t => t.Employee)
.HasForeignKey<Employee>(t => t.Id).IsRequired();
Run Code Online (Sandbox Code Playgroud)
第一部分中使用的参数d
类型为CompanyVehicle
。所以我们的迁移器将旧代码转换为:
b.HasOne(t => t.CompanyVehicle)
.WithOne(t => t.Employee)
.HasForeignKey<CompanyVehicle>(t => t.Id).IsRequired();
Run Code Online (Sandbox Code Playgroud)
这是不正确的。通用参数应该是依赖的表类型。我们后来在新的命名空间中修复了该问题,但该ApplyConfigurationsFromAssembly
方法在我们的配置后也继续应用过时的代码。
我在末尾使用了以下代码块OnModelCreating
来调查该问题:
foreach (var entity in modelBuilder.Model.GetEntityTypes())
foreach(var key in entity.GetForeignKeys())
{
//Check what is in the key...
}
Run Code Online (Sandbox Code Playgroud)
并注意到为我的实体配置了重复的键。
归档时间: |
|
查看次数: |
22913 次 |
最近记录: |