5

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);

ERM: enter image description here

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'.'

1
  • See EDIT (11.03.2017). Commented Mar 11, 2017 at 10:02

1 Answer 1

9

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. The order of the inserts solved the problem. Additionally I had to allow NULL for the CurrentHandling Column.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.