EF Core multiple navigation properties produce circular dependency

一笑奈何 提交于 2021-01-04 06:08:57

问题


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:

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



来源:https://stackoverflow.com/questions/42719796/ef-core-multiple-navigation-properties-produce-circular-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!