表拆分 EF Core

And*_*äck 5 .net c# entity-framework .net-core ef-core-3.1

我正在尝试在 EF 核心中使用表拆分。我有一个 int 属性,我想在存储在同一个表中的两个实体之间共享它。

我收到一个 InvalidOperationException,说共享同一列的属性具有不同的可空性。

我使用 EF Core Docs 中的表拆分示例重新创建了该问题。

https://docs.microsoft.com/en-us/ef/core/modeling/table-splitting https://github.com/aspnet/EntityFramework.Docs/tree/master/samples/core/Modeling/TableSplitting

public class Order
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public int SharedInt { get; set; }
    public DetailedOrder DetailedOrder { get; set; }
}

public class DetailedOrder
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public string BillingAddress { get; set; }
    public string ShippingAddress { get; set; }
    public int SharedInt { get; set; }
    public byte[] Version { get; set; }
}

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            #region TableSplitting
            modelBuilder.Entity<DetailedOrder>(dob =>
            {
                dob.ToTable("Orders");
                dob.Property(o => o.Status).HasColumnName("Status");
                dob.Property(p => p.SharedInt).HasColumnName("Shared");
            });

            modelBuilder.Entity<Order>(ob =>
            {
                ob.ToTable("Orders");
                ob.Property(o => o.Status).HasColumnName("Status");
                ob.Property(p => p.SharedInt).HasColumnName("Shared");

                ob.HasOne(o => o.DetailedOrder).WithOne()
                    .HasForeignKey<DetailedOrder>(o => o.Id);
            });

            #endregion

            #region ConcurrencyToken
            modelBuilder.Entity<Order>()
                .Property<byte[]>("Version").IsRowVersion().HasColumnName("Version");

            modelBuilder.Entity<DetailedOrder>()
                .Property(o => o.Version).IsRowVersion().HasColumnName("Version");
            #endregion
        }
Run Code Online (Sandbox Code Playgroud)

当我运行示例时,出现异常:

System.InvalidOperationException:“DetailedOrder.SharedInt”和“Order.SharedInt”都映射到“Orders”中的“Shared”列,但配置为具有不同的可空性。

如果我不将属性映射到特定列,则将其留给 EF Core。我可以看到(在创建的迁移中查看)其中一个属性是可为 null == true 尽管它是一个不可为 null 的 int。

 protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Orders",
                columns: table => new
                {
                    Id = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Status = table.Column<int>(nullable: true),
                    Order_SharedInt = table.Column<int>(nullable: false),
                    BillingAddress = table.Column<string>(nullable: true),
                    ShippingAddress = table.Column<string>(nullable: true),
                    SharedInt = table.Column<int>(nullable: true),
                    Version = table.Column<byte[]>(rowVersion: true, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Orders", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Orders");
        }
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

Iva*_*oev 4

不幸的是,目前(EF Core 3.1)没有解决方案。

这是以下 EF Core 3.0 重大更改的副作用 -与主体共享表的依赖实体现在是可选的

有趣的是,他们认为它的影响很小,但它的实现方式(通过使所有依赖的非键属性可为空)破坏了很多东西,包括他们自己的表拆分示例。

看起来该问题被#12100 跟踪为增强请求(?!):启用配置所需的一对一依赖项,并具有未知的解决时间范围(最终考虑“下一个”版本,无论这意味着什么)。所有报告的相关问题(例如#18574:表分割不适用于不可为空的引用类型。这与此类似)都作为“重复”关闭,尽管它实际上是一种回归。