Обновление связанной модели без первоначального поиска родителя, но с заполнением при обновлении - PullRequest
0 голосов
/ 10 мая 2018

Я использую ef-core 2.1 rc1, у меня есть зависимая модель со свойством навигации, определенным как сложный объект:

public class ChildModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ParentModel Parent { get; set; }
}

В представлении я получаю Id и обновленный Name, Я могу обновить объект, не выбирая свойство навигации, однако я хотел бы получить свойство навигации после обновления.В следующем случае его значение равно нулю, даже если Include было вызвано:

this.context.Update(childInstance);
await this.context.SaveChangesAsync();
Child child = await this.context.Children
    .Include(p => p.Parent)
    .SingleAsync(p => p.Id == childInstance.Id);

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

1 Ответ

0 голосов
/ 10 мая 2018

Проблема в том, что childInstance присоединен к контексту и считается текущим с теневым FK ParentId, являющимся null трекером изменений, поэтому любой последующий объект, возвращающий запрос с тем же PK, будет игнорироваться и просто заменен на этот экземпляр.

Один из способов исправить это - отсоединить экземпляр сущности после сохранения:

await this.context.SaveChangesAsync();
this.context.Entry(childInstance).State = EntityState.Detached;

или перезагрузите его из базы данных:

await this.context.SaveChangesAsync();
await this.context.Entry(childInstance).ReloadAsync();

Теперь вы можете загрузить свойство навигации:

await this.context.Entry(childInstance).Reference(c => c.Parent).LoadAsync();

Но как только вам понадобится извлечь некоторые данные из базы данных после обновления, возможно, лучшим подходом будет отменить процедуру, сначала загрузив экземпляр сущности из базы данных, а затем применив изменения. Дополнительным преимуществом является то, что в команду UPDATE будут включены только измененные свойства (или вообще не будут обновляться):

var dbChild = await this.context.Children
    .Include(p => p.Parent)
    .SingleAsync(p => p.Id == childInstance.Id);

// Update properties
dbChild.Name = childInstance.Name;
// ...

// Or more generically
this.context.Entry(dbChild).CurrentValues.SetValues(childInstance);

await this.context.SaveChangesAsync();
...