EF удалить объект с выгруженным свойством навигации - PullRequest
2 голосов
/ 21 октября 2011

У меня есть сущность.Mandate.Каждый мандат имеет обязательное: много отношение к человеку (NavigationProperty).Я использую API DbContext с (LazyLoadingEnabled, AutoDetectChangesEnabled, ValidateOnSaveEnabled, ProxyCreationEnabled)

Теперь мне нравится удалять объект Mandate.Объекты мандата загружаются другим контекстом с AsNoTracking().

message.Result.
    ObserveOn(On<DataComposition>.Scheduler).
    Where(r => r).
    Subscribe(_ =>
    {
        using (var unit = UnitOfWork.Begin())
        {
            var mandate = this.SelectedItem.OriginalEntity;

            this.mandateRepository.Attach(mandate);
            // mandate.Person.ToString();

            this.mandateRepository.Delete(mandate);

            unit.Commit();
        }

        this.List.RemoveOnUi(this.SelectedItem);
    });

Теперь при фиксации я получаю следующее исключение: Entities in 'CodeFirstContainer.Mandates' participate in the 'Mandate_Person' relationship. 0 related 'Mandate_Person_Target' were found. 1 'Mandate_Person_Target' is expected.

Удаление работает, если я включаю свойство Person во время заполнения / выбора или если я посещаю свойство (lazyloading), но я DONT LIKE для материализации / хранения многих сущностей только для случая удаления, а I DONT LIKE для запуска более одного DELETE запроса к базе данных!

1 Ответ

2 голосов
/ 21 октября 2011

Тот факт, что, если у вас заполнено свойство навигации mandate.Person, следующий оператор SQL ...

delete [dbo].[Mandates]
where (([Id] = @0) and ([PersonId] = @1))

... отправлено в базу данных, позволяет мне думать, что свойство навигации действительно должно быть заполнено человеком с правильным PersonId для удаления родителя.

Понятия не имею, почему Entity Framework просто не отправляет оператор удаления с первичным ключом ...

delete [dbo].[Mandates]
where ([Id] = @0)

... как я и ожидал.

Редактировать

Если объект Mandate имеет свойство внешнего ключа PersonId для свойства навигации Person, ожидаемый SQL (второй выше) отправляется в базу данных. В этом случае свойство навигации Person может иметь значение null, а значение свойства FK PersonId не имеет значения.

Редактировать 2

Если вы не хотите вводить свойство FK, способ с наименьшими затратами DB-roundtrip, вероятно, будет заключаться в получении идентификатора человека и последующем создании фиктивного человека с этим ключом в памяти:

// ...
var personId = context.Mandates
    .Where(m => m.Id == mandate.Id)
    .Select(m => m.Person.Id)
    .Single();

mandate.Person = new Person { Id = personId };

this.mandateRepository.Attach(mandate);
this.mandateRepository.Delete(mandate);
// ...
...