我正在尝试在具有复合主键的EF Core存储库中拆分表。但是它生成一个InvalidOperationException,表示它无法在派生表上找到主键。
“实体类型'DetailedOrder'需要定义主键。'
为了对其进行测试,我从EntityFramework.Docs repository中提取了用于表拆分的示例代码,并对其进行了修改,使其包括复合PK:
public class Order
{
public int OrderId { get; set; }
public int Rev { get; set; }
public OrderStatus Status { get; set; }
public DetailedOrder DetailedOrder { get; set; }
}
public class DetailedOrder : Order
{
public string BillingAddress { get; set; }
public string ShippingAddress { get; set; }
public byte[] Version { get; set; }
}
public class TableSplittingContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<DetailedOrder> DetailedOrders { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Server = 20.0.5.64\\SQLEXPRESS; Database=EFSamples;User Id = cp; Password=crest1*");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DetailedOrder>()
.ToTable("Orders")
.HasBaseType((string)null)
.Ignore(o => o.DetailedOrder);
modelBuilder.Entity<Order>(
entity =>
{
entity.HasKey(ck => new { Id = ck.OrderId, ck.Rev });
entity.ToTable("Orders")
.HasOne(o => o.DetailedOrder).WithOne()
.HasForeignKey<Order>(o => new { Id = o.OrderId, o.Rev });
});
}
}
答案 0 :(得分:3)
实体类型'DetailedOrder'需要定义主键。
必须为所有实体明确定义(复合)PK,而EF Core naming conventions无法自动导出PK。该示例使用的是名为 "paths": {
"rxjs/*": ["node_modules/rxjs/*"],
}
的PK,这就是为什么它不需要其他配置的原因。
使用表拆分的已发布模型的正确配置应如下所示:
Id
实际上,规则的一对一关系和表拆分之间的唯一区别是modelBuilder.Entity<DetailedOrder>(entity =>
{
entity.HasBaseType((string)null)
.Ignore(o => o.DetailedOrder);
entity.HasKey(o => new { o.OrderId, o.Rev }); // <--
entity.ToTable("Orders");
});
modelBuilder.Entity<Order>(entity =>
{
entity.HasKey(o => new { o.OrderId, o.Rev }); // <--
entity.ToTable("Orders");
entity.HasOne(o => o.DetailedOrder).WithOne()
.HasForeignKey<Order>(o => new { Id = o.OrderId, o.Rev });
});
流利配置为主体和从属实体指定了一张相同的表。实体配置的其他部分应该与没有表拆分的情况相同。