由于Entity Framework Core中的循环依赖性而导致InvalidOperationException

时间:2017-08-31 16:53:53

标签: c# sql entity-framework entity-framework-core

当我尝试以一对一的关系保存实体时,我收到以下 InvalidOperationException

  

System.InvalidOperationException:无法保存更改,因为a   在要保存的数据中检测到循环依赖:'ForeignKey:   DeviceLicenseSubscriptionPlan {'LicenseId'} - > DeviceLicense {'Id'}   唯一ToPrincipal:许可证,ForeignKey:DeviceLicense   {'SubscriptionPlanId'} - > DeviceLicenseSubscriptionPlan {'Id'}   ToPrincipal:SubscriptionPlan'。

这是我的模式:

public class DeviceLicense
{
    public Guid? Id { get; set; }
    public int DeviceLimit { get; set; }
    public DeviceLicenseSubscriptionPlan SubscriptionPlan { get; set; } = new DeviceLicenseSubscriptionPlan();
}

public class DeviceLicenseSubscriptionPlan 
{
    public Guid? Id { get; set; }
    public Guid? LicenseId { get; set; }
    public DeviceLicense License { get; set; }
}

此处为OnModelCreating()

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var deviceLicense = modelBuilder.Entity<DeviceLicense>().ToTable("DeviceLicense");
    deviceLicense.HasKey(l => l.Id);
    deviceLicense.HasOne<DeviceLicenseSubscriptionPlan>()
        .WithOne(s => s.License)
        .HasForeignKey<DeviceLicenseSubscriptionPlan>(s => s.LicenseId)
        .HasConstraintName("LicenseId");
    deviceLicense.Property(l => l.DeviceLimit).HasColumnName("DeviceLimit");

    var deviceLicenseSubPlan = modelBuilder.Entity<DeviceLicenseSubscriptionPlan>().ToTable("DeviceLicenseSubscriptionPlan");
    deviceLicenseSubPlan.HasKey(s => s.Id);
    deviceLicenseSubPlan.Property(s => s.Id).HasColumnName("SubscriptionPlanId");


    base.OnModelCreating(modelBuilder);
}

我正在使用EF Core 2.0。我可能在ModelBuilder中做错了什么?任何提示?

1 个答案:

答案 0 :(得分:4)

问题在于这一行

deviceLicense.HasOne<DeviceLicenseSubscriptionPlan>()

它基本上告诉EF DeviceLicenseSubscriptionPlanDeviceLicense没有导航属性。但是是导航属性,因此按惯例,EF将其映射到DeviceLicense中指向DeviceLicenseSubscriptionPlan的FK的第二个关系。当然,DeviceLicenseSubscriptionPlan中所需FK的组合会创建一个循环。

确保流畅配置使用正确的重载,这些重载准确表示关系任一侧是否存在导航属性。在这种特殊情况下,用

替换上面的内容
deviceLicense.HasOne(l => l.SubscriptionPlan)