I'm trying to use table spliting in EF core. I have an int property that I want to share between two entities stored in the same table.
I get an InvalidOperationException saying that the properties sharing the same column have different nullability.
I have recreated the problem using the Table splitting sample from 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
}
When I run the sample I get an exception:
System.InvalidOperationException: ''DetailedOrder.SharedInt' and 'Order.SharedInt' are both mapped to column 'Shared' in 'Orders' but are configured with different nullability.'
If I don't map the properties to specific columns, leaving it to EF Core. I can see (looking in the created migration) that one of the properties is nullable == true despite it beeing an non-nullable 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");
}
Any thoughts?
Unfortunately currently (EF Core 3.1) there is no solution.
This is a side effect of the following EF Core 3.0 breaking change - Dependent entities sharing the table with the principal are now optional.
Interestingly, they consider it having Low impact, but the way it is implemented (by making all dependent non key properties nullable) is breaking many things, including their own table splitting example.
Looks like the issue is tracked as enhancement request (?!) by #12100: Enable configuring required 1-to-1 dependents with unknown timeframe for addressing (eventually consider for "next" release, whatever that means). All reported related issues (for instance #18574: Table splitting isn't working with nonnullable reference types. which is similar to this one) are closed as "duplicate", although it's really a regression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With