I have 2 objects with a FK relationship between them. All of this logic worked fine when i was using .net core 2, but broke when i upgraded to 2.1
public class Parent
{
[Key()]
public Guid ParentGUID {get;set;}
public string SomeValue {get;set;}
[ForeignKey("ReferenceTypeGUID")]
public ReferenceType ReferenceTypeObject {get;set;}
}
public class ReferenceType
{
[Key()]
public Guid ReferenceTypeGUID{get;set;}
public string SomeOtherValue {get;set;}
public virtual ICollection<Parent> ParentGU { get; set; }
}
and then in my dbcontext i have
modelBuilder.Entity<ReferenceType>(entity =>
{
entity.HasKey(e => e.ReferenceTypeGUID);
entity.HasMany(c => c.ParentGU)
.WithOne(e => e.ReferenceTypeObject)
.HasForeignKey(f => f.ParentGUID)
.OnDelete(DeleteBehavior.ClientSetNull);
});
Now in my original code, i didn't have the HasForeignKey line, and i got the following error:
cannot target the primary key because it is not compatible
adding that line fixed that issue, but now i'm getting
Operand type clash: int is incompatible with uniqueidentifier
for some reason, EF is assuming that the database type should be int instead of uniqueidentifier, even though the object is declared as a GUID. how do i fix this issue?
Looks like EF Core 2.1 has introduced a bug when you define a shadow FK property via ForeignKey
annotation (frankly I didn't know this is supported at all). It incorrectly assumes int
or int?
type for that shadow property rather than considering the referenced PK property type.
You might fill an issue in their issue tracker if you wish. But I won't recommend using ForeignKey
attribute for that purpose (or data annotations for relationships at all).
You can fix it by adding the following to the Parent
entity fluent configuration:
entity.Property<Guid?>("ReferenceTypeGUID");
but this makes sense if you want to configure let say a different database column name for the shadow property.
A better (IMO) way is to remove the ForeignKey
attribute and simply use the HasForeignKey
overload with string foreignKeyPropertyNames
parameter:
entity.HasMany(c => c.ParentGU)
.WithOne(e => e.ReferenceTypeObject)
.HasForeignKey("ReferenceTypeGUID") // <--
.OnDelete(DeleteBehavior.ClientSetNull);