Null FK's on self-referencing entities are changed to -2147482647 resulting in foreign key constraint exception
File a bug
Issue
Self referencing entities seem to have their null FK's set to -2147482647 when creating new entities. I'm actually unsure how to work around this off the top of my head 🤔
Include your code
👉 If the issue isn't immediately obvious and we need a runnanble project, please LMK and I will make one. 👈
// Other non-relevant properties chopped out
public class Company : TenantBase
{
public Company? BillingOwner { get; private set; }
public int? BillingOwnerId { get; private set; }
}
// Other non-relevant properties chopped out
public class TenantBase
{
public int Id { get; private set; }
public int? ParentId { get; private set; }
public TenantBase? Parent { get; private set; }
}
public class CompanyEntityConfig : IEntityTypeConfiguration<Company>
{
public void Configure(EntityTypeBuilder<Company> builder)
{
builder.HasOne(x => x.BillingOwner)
.WithMany()
.HasForeignKey(x => x.BillingOwnerId)
// .IsRequired() // Would be nice to make this required, but how with new entities?
.OnDelete(DeleteBehavior.Restrict);
}
}
public class TenantEntityConfig : IEntityTypeConfiguration<TenantBase>
{
public void Configure(EntityTypeBuilder<TenantBase> builder)
{
builder.HasKey(x => x.Id);
// Sets up "Table Per Hierarchy" https://learn.microsoft.com/en-us/ef/core/modeling/inheritance#table-per-hierarchy-and-discriminator-configuration
builder.HasDiscriminator<string>("TenantType")
.HasValue<Company>(nameof(Company));
}
}
NOTE: Using IsRequired() and public int BillingOwnerId doesn't appear to make any change.
Include stack traces
Include the full exception message and stack trace for any exception you encounter.
Use triple-tick fences for stack traces. For example:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Npgsql.PostgresException (0x80004005): 23503: insert or update on table "tenants" violates foreign key constraint "fk_tenants_tenants_billing_owner_id"
DETAIL: Key (billing_owner_id)=(-2147482647) is not present in table "tenants".
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Exception data:
Severity: ERROR
SqlState: 23503
MessageText: insert or update on table "tenants" violates foreign key constraint "fk_tenants_tenants_billing_owner_id"
Detail: Key (billing_owner_id)=(-2147482647) is not present in table "tenants".
SchemaName: public
TableName: tenants
ConstraintName: fk_tenants_tenants_billing_owner_id
File: ri_triggers.c
Line: 2528
Routine: ri_ReportViolation
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Buzzscreens.Infrastructure.DbContextHooks.HookableDbContext`3.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) in C:\Users\Douglas\Documents\01 Programming\02 Contracts\buzzscreens-app\apps\backend\Buzzscreens.Infrastructure\DbContextHooks\HookableDbContext.cs:line 85
Include provider and version information
EF Core version: 8.08
Database provider: Postgres
Target framework: .Net 8
Operating system: Windows 10
IDE: Rider
This issue is lacking enough information for us to be able to fully understand what is happening. Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.
EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it.
BTW this is a canned response and may have info or details that do not directly apply to this particular issue. While we'd like to spend the time to uniquely address every incoming issue, we get a lot traffic on the EF projects and that is not practical. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we use canned responses for common triage decisions.