Wrong parameter sent when setting a foreign key
See original GitHub issueEF Core version: 2.1.2 Database Provider: Npgsql.EntityFrameworkCore.PostgreSQL v2.1.1.1
Using the following entity:
[Table("caps_user_shares")]
internal class CapsUserShareEntity
{
[Column("caps_id")]
public Guid CapsId { get; set; }
[Column("user_id")]
public Guid UserId { get; set; }
[Column("location")]
[Required] public Point Location { get; set; }
public CapsEntity Caps { get; set; }
public UserAccountEntity User { get; set; }
}
and the following foreign key rule:
modelBuilder.Entity<CapsUserShareEntity>().HasOne(s => s.User).WithMany().HasForeignKey(s => s.UserId);
I tried to add such an entity and set its UserId
to Guid.Empty
which corresponds to a (special) user that exists in the DB:
Context.CapsUserShares.Add(new CapsUserShareEntity
{
CapsId = @event.EntityId,
UserId = Guid.Empty,
Location = PointFromLocationModel(@event.Location)
});
This failed with a violation of the foreign key constraint I described above. Tracing the SQL statements with EnableSensitiveDataLogging
, I saw that the parameter sent for the user_id
column was not Guid.Empty
but some other Guid that I couldn’t match with anything else in the DB (so presumably the result of a Guid.NewGuid()
).
The workaround I found was to set the User
property to that special user I had to retrieve first:
var publicUser = await Context.UserAccounts.FirstOrDefaultAsync(a => a.Id == Guid.Empty);
...
Context.CapsUserShares.Add(new CapsUserShareEntity
{
CapsId = @event.EntityId,
User = publicUser,
Location = PointFromLocationModel(@event.Location)
});
This approach does result in the right parameter being sent.
My intuition is that Guid.Empty
being default(Guid)
, it is not considered as a set value by EF?
Issue Analytics
- State:
- Created 5 years ago
- Comments:10 (4 by maintainers)
@ajcvickers Thanks a lot for that clarification. For those running in the same issue and looking at my repro, the problem got solved by applying the
[DatabaseGenerated(DatabaseGeneratedOption.None)]
attribute to theId
ofUserEntity
.@ThomasWeiss Yes, the DatabaseGeneratedOption needs to go on the primary key–sorry I wasn’t clear about this. This is because when generating key values it is very unusual that a key value should be generated directly for an FK property, since it would not match any existing PK. Instead, PK values typically get their value via propagation from the primary key value, rather than having a new value generated.