c# - 在 EF Core 数据库上使用复合主键拆分表

标签 c# .net entity-framework-core

我正在尝试拆分 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 });
                    });

    }
}

最佳答案

The entity type 'DetailedOrder' requires a primary key to be defined.

必须为 EF Core 无法自动派生 PK 的所有实体显式定义(复合)PK naming conventions 。该示例使用名为 Id 的 PK,这就是它不需要额外配置的原因。

发布的带有表格分割的模型的正确配置应该是这样的:

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 });
});

事实上,常规一对一关系和表拆分之间的唯一区别是 ToTable 流畅配置为主体和依赖实体指定同一个表。实体配置的其他部分应该与没有表拆分时相同。

关于c# - 在 EF Core 数据库上使用复合主键拆分表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56751939/

相关文章:

c# - 在 C++ 中使用 Mono 获取程序集类

c# - 具有不同列的求和查询

c# - 如何使用反射来查找实现特定接口(interface)的属性?

c# - 告诉 WPF 评估绑定(bind)

c# - 开放通用类型是否被认为是具体的?我们如何通过参数化来限定抽象?

.net - 以编程方式生成 SAS token C#

asp.net-core - EntityFrameworkCore 上的 scaffold-dbcontext basepath 异常

asp.net-core-mvc - 如何在 Entity Framework 核心中导航多对多关系

c# - Docker-compose 从另一个容器访问 MySQL 容器

C#:VS 2008 调试器执行属性代码