即使使用注释,Entity Framework Core也无法解析反向属性

she*_*mus 0 c# entity-framework entity-framework-6 entity-framework-core

我把它归结为一个非常小的用例:

public class ItemRental
{
    [Key]
    public Int32 ItemRentalId { get; set; }

    public Int32? OriginatingSalesOrderId { get; set; }

    [ForeignKey("OriginatingSalesOrderId")]
    public SalesOrder OriginatingSalesOrder { get; set; }

    public Int32? DepositCreditedOnSalesOrderId { get; set; }

    [ForeignKey("DepositCreditedOnSalesOrderId")]
    public SalesOrder DepositCreditedOnSalesOrder { get; set; }
}

public class SalesOrder
{

    [Key]
    public Int32 SalesOrderId { get; set; }

    [InverseProperty("OriginatingSalesOrder")]
    public ICollection<ItemRental> Rentals { get; set; }


    [InverseProperty("DepositCreditedOnSalesOrder")]
    public ICollection<ItemRental> Refunds { get; set; }
}

public class MyAppDatabase : DbContext
{
    public MyAppDatabase(DbContextOptions<MyAppDatabase> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(x => x.GetForeignKeys()))
        {
            relationship.DeleteBehavior = DeleteBehavior.Restrict;
        }
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<ItemRental> ItemRentals { get; set; }
    public DbSet<SalesOrder> SalesOrders { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

尝试运行迁移将给出:

System.InvalidOperationException:无法确定由"SalesOrder"类型的导航属性"ItemRental.OriginatingSalesOrder"表示的关系.手动配置关系,或使用'[NotMapped]'属性或在'OnModelCreating'中使用'EntityTypeBuilder.Ignore'忽略此属性.

对于EF 6.x,这种相同的关系完全没问题.我相信我可以使用Fluent API解决这个问题,但我更愿意了解如何使用注释来完成这项工作.

我在这里发现了一个类似的问题:EntityFramework在进行Add-Migration时的核心模型关系问题但它并没有解决这个问题.

编辑:示例解决方案:https://drive.google.com/file/d/0BzgvtZfXt8MHd1RseVJubmd6TEU/view?usp=sharing

Iva*_*oev 5

这里没有什么可以理解的,因为您的数据注释是完全有效的.

问题的原因更为简单 - #9180元数据跟踪的EF Core 2.0(回归)错误:InverseProperty无法解决在EFC问题跟踪器中使用KeyAttribute打开PK问题时的歧义,计划用于下一个2.1版本.

在此之前,链接中建议的解决方法是使用流畅的API,但如果KeySalesOrderId属性中删除属性,它也可以工作SalesOrder(因为它幸运地遵循了公认的PK约定之一):

public class SalesOrder
{    
    public Int32 SalesOrderId { get; set; }    
    // ...
}
Run Code Online (Sandbox Code Playgroud)

或者如果您InverseProperty在集合导航属性上应用该属性:

public class ItemRental
{
    // ...
    [ForeignKey("OriginatingSalesOrderId")]
    [InverseProperty("Rentals")]
    public SalesOrder OriginatingSalesOrder { get; set; } 
    // ...    
    [ForeignKey("DepositCreditedOnSalesOrderId")]
    [InverseProperty("Refunds")]
    public SalesOrder DepositCreditedOnSalesOrder { get; set; }
}
Run Code Online (Sandbox Code Playgroud)