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

Mar*_*ndl 1 c# sql entity-framework entity-framework-core

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

System.InvalidOperationException:无法保存更改,因为在要保存的数据中检测到循环依赖项:'ForeignKey: DeviceLicenseSubscriptionPlan {'LicenseId'} -> DeviceLicense {'Id'} Unique ToPrincipal: License, 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; }
}
Run Code Online (Sandbox Code Playgroud)

这里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);
}
Run Code Online (Sandbox Code Playgroud)

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

Iva*_*oev 5

问题是这条线

deviceLicense.HasOne<DeviceLicenseSubscriptionPlan>()
Run Code Online (Sandbox Code Playgroud)

它基本上告诉 EF DeviceLicenseSubscriptionPlanin没有导航属性DeviceLicense。但是有一个导航属性,因此 EF 按照约定将其映射到与 FKDeviceLicense指向的第二个关系DeviceLicenseSubscriptionPlan。这当然与所需 FK 的组合DeviceLicenseSubscriptionPlan创建了一个循环。

确保流畅的配置使用正确的重载,这些重载准确地表示关系任一侧导航属性的存在/不存在。在这种特殊情况下,将上述内容替换为

deviceLicense.HasOne(l => l.SubscriptionPlan)
Run Code Online (Sandbox Code Playgroud)