Reputation: 988
I have the following mapping configuration:
Entry-Class:
entity
.HasOne(e => e.CurrentHandling)
.WithOne()
.HasForeignKey<Entry>(e => e.CurrentHandlingID)
;
entity
.HasMany(e => e.Handlings)
.WithOne(h => h.Entry)
.HasForeignKey(h => h.EntryID)
;
Handling-Class:
entity
.HasOne(h => h.Entry)
.WithMany(e => e.Handlings)
.HasForeignKey(h => h.EntryID)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
When I try to save the context I get the following exception:
System.InvalidOperationException: 'Unable to save changes because a circular dependency was detected in the data to be saved: 'ForeignKey: Entry.CurrentHandlingID -> Handling.HandlingID Unique ToPrincipal: CurrentHandling, ForeignKey: Handling.EntryID -> Entry.EntryID ToDependent: Handlings ToPrincipal: Entry'.'
Test-Data:
errorRepo.EnableBulkModus();
var handling = errorRepo.AddHandling(new Handling {
CorrectedMessage = "correct",
HandlingStatusID = 7,
Updated = DateTime.UtcNow,
UpdatedBy = nameof(DbInitializer)
});
var reference = errorRepo.AddReference(new Reference {
ForeignKeyTypeID = 4,
ForeignKeyValue = "42",
Name = "SystemB",
ReferenceTypeID = 6
});
var entry = errorRepo.AddEntry(new Entry {
CurrentHandling = handling,
DisplayMessage = "Wrong!",
ErrorMessage = "error!",
Inserted = DateTime.UtcNow.AddMinutes(-5),
OriginalMessage = "incorrect",
InsertedBy = nameof(DbInitializer),
UUID = Guid.NewGuid(),
Reference = reference,
StatusID = 5
});
handling.Entry = entry;
entry.Handlings.Add(handling);
errorRepo.DisableBulkModus(true);
errorRepo.EnableBulkModus();
sets just a flag which indicates the repository not to save when calling CommitChanges()
Same with errorRepo.DisableBulkModus(true);
, it sets the flag to false. The boolean indicated, that the repository should perform a CommitChanges()
.
How do I have to change my mapping to avoid a circular dependency?
kind Regards.
EDIT (11.03.2017)
I removed the mapping from the Handling-Class and added the line .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict)
in the Entry-Class:
entity
.HasMany(e => e.Handlings)
.WithOne(h => h.Entry)
.HasForeignKey(h => h.EntryID)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict)
;
Same exception:
System.InvalidOperationException: 'Unable to save changes because a circular dependency was detected in the data to be saved: 'ForeignKey: Entry.CurrentHandlingID -> Handling.HandlingID Unique ToPrincipal: CurrentHandling, ForeignKey: Handling.EntryID -> Entry.EntryID ToDependent: Handlings ToPrincipal: Entry'.'
Upvotes: 5
Views: 3136
Reputation: 109347
See this:
// 1.
var entry = errorRepo.AddEntry(new Entry {
CurrentHandling = handling,
...
});
...
// 2.
handling.Entry = entry;
The code below 1. requires entry
to receive handling
's primary key as foreign key. The code below 2. requires handling
to reveive entry
's primary key as FK: a chicken-and-egg problem.
Since handling
depends on entry
(because of the 1-0..1 relationship), entry
should be inserted first --not having its CurrentHandling
property set yet. Then save changes, so entry
knows its generated PK. Then set entry.CurrentHandling
and handling.Entry
and save changes again.
You may want to wrap this code in a transaction.
By the way, the line entry.Handlings.Add(handling);
is redundant.
Upvotes: 9