Ricevo la seguente InvalidOperationException quando provo a salvare un'entità con una relazione uno a uno:
System.InvalidOperationException: impossibile salvare le modifiche perché è stata rilevata una dipendenza circolare nei dati da salvare: "ForeignKey: DeviceLicenseSubscriptionPlan {'LicenseId'} -> DeviceLicense {'Id'} Unique ToPrincipal: License, ForeignKey: DeviceLicense {'SubscriptionPlanId' } -> DeviceLicenseSubscriptionPlan {'Id'} ToPrincipal: SubscriptionPlan '.
Ecco il mio modello:
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; }
}
Qui 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);
}
Sto usando EF Core 2.0. Probabilmente faccio qualcosa di sbagliato all'interno del ModelBuilder? Qualche suggerimento?
Il problema è questa linea
deviceLicense.HasOne<DeviceLicenseSubscriptionPlan>()
In pratica dice a EF che non esiste alcuna proprietà di navigazione per DeviceLicenseSubscriptionPlan
in DeviceLicense
. Tuttavia esiste una proprietà di navigazione , quindi EF per convenzione lo associa a una seconda relazione con FK in DeviceLicense
punta a DeviceLicenseSubscriptionPlan
. Che naturalmente con la combinazione dell'FK desiderato in DeviceLicenseSubscriptionPlan
crea un ciclo.
Assicurati che la fluente configurazione utilizzi i sovraccarichi corretti che rappresentano esattamente la presenza / assenza di una proprietà di navigazione in entrambi i lati della relazione. In questo caso particolare, sostituire il precedente con
deviceLicense.HasOne(l => l.SubscriptionPlan)