Upgrade to 2.1 breaks existing .net core EF logic

时间:2018-06-04 16:42:30

标签: entity-framework asp.net-core entity-framework-core asp.net-core-2.1

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 个答案:

答案 0 :(得分:2)

看起来EF Core 2.1在通过ForeignKey注释定义阴影FK属性时引入了一个错误(坦率地说,我并不知道这完全支持)。它错误地假定该阴影属性为intint?类型,而不是考虑引用的PK属性类型。

如果您愿意,可以在问题跟踪器中填写问题。但我不建议为此目的使用ForeignKey属性(或者根本就是关系的数据注释)。

您可以通过将以下内容添加到Parent实体流畅配置来修复它:

entity.Property<Guid?>("ReferenceTypeGUID");

但是,如果要为shadow属性配置一个不同的数据库列名,这是有意义的。

更好的(IMO)方式是删除 ForeignKey属性,只需将HasForeignKey重载与string foreignKeyPropertyNames参数一起使用:

entity.HasMany(c => c.ParentGU)
    .WithOne(e => e.ReferenceTypeObject)
    .HasForeignKey("ReferenceTypeGUID") // <--
    .OnDelete(DeleteBehavior.ClientSetNull);