Upgrade to 2.1 breaks existing .net core EF logic

asp.net-core asp.net-core-2.1 entity-framework entity-framework-core

Question

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?

1
2
6/4/2018 4:55:12 PM

Accepted Answer

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);
2
6/4/2018 7:05:53 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow