Почему функция DbContext.Update() EF Core сохраняет исходные дочерние объекты в БД, а в других случаях — нет?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Почему функция DbContext.Update() EF Core сохраняет исходные дочерние объекты в БД, а в других случаях — нет?

Сообщение Anonymous »

Мое приложение ASP.NET Core Web API использует SQL Server, и у меня есть следующая служба, зарегистрированная в Microsoft.DependencyInjection как служба с заданной областью:

Код: Выделить всё

public class UpdateOperation(
IMapper mapper,
ApplicationDbContext dbContext,
ICurrentUtcTimeProvider currentUtcTimeProvider)
: IUpdateOperation
where TEntity : UserEntityBase
where TDto : DtoBase
{
private readonly IMapper _mapper = mapper;
private readonly ApplicationDbContext _dbContext = dbContext;
private readonly ICurrentUtcTimeProvider _currentUtcTimeProvider = currentUtcTimeProvider;

/// 
public async Task UpdateAsync(TEntity? existingEntity, TDto newDto, string userId)
{
if (existingEntity is null)
return;

_mapper.Map(newDto, existingEntity);

if (existingEntity is IUpdateHistory entityUpdateHistory)
{
entityUpdateHistory.UpdatedAt = _currentUtcTimeProvider.GetCurrentUtcTime();
entityUpdateHistory.UpdatedBy = userId;
}

_dbContext.Update(existingEntity);

await _dbContext.SaveChangesAsync();
}
}
И более старая служба, которая просто изменяет некоторые свойства объекта IUpdateHistory:

Код: Выделить всё

public class UpdateInfoOperation(
ICurrentUtcTimeProvider currentUtcTimeProvider)
: IUpdateInfoOperation
{
private readonly ICurrentUtcTimeProvider _currentUtcTimeProvider = currentUtcTimeProvider;

/// 
public void UpdateInfo(IUpdateHistory entity, string userId)
{
ArgumentNullException.ThrowIfNull(userId);

entity.UpdatedBy = userId;
entity.UpdatedAt = _currentUtcTimeProvider.GetCurrentUtcTime();
}
}
Затем у меня есть службы репозитория, которые используют одну из служб. Если они используют UpdateInfoOperation и сами вызывают метод DbContext.Update(), все работает нормально:

Код: Выделить всё

/// 
public async Task UpdateAsync(Guid id, RailLineDto newDto, string userId)
{
RailLine? existingEntity = await FindEntityByIdAsync(id, userId);
if (existingEntity == null)
return;

_mapper.Map(newDto, existingEntity);
_updateInfoOperation.UpdateInfo(existingEntity, userId);

_dbContext.Update(existingEntity);

await _dbContext.SaveChangesAsync();
}

/// 
/// Asynchronously finds a RailLine entity by its identifier and user ID.
/// 
/// 
The ID of the RailLine entity to find.
/// The ID of the user who owns the entity.
/// A task that represents the asynchronous operation. The task result contains the RailLine entity if found; otherwise, null.
private async Task FindEntityByIdAsync(Guid id, string userId)
{
return await
_dbContext.RailLines
.Include(l => l.Stations)
.Include(l => l.SpeedSections)
.Include(l => l.Gradients)
.Include(l => l.Curves)
.Include(l => l.Tunnels)
.Include(l => l.ElectrifiedSections)
.Include(l => l.Substations)
.FirstOrDefaultAsync(l => l.Id == id && l.UserId == userId && !l.IsDeleted);
}
Но когда они используют UpdateOperation и метод выше просто вызывает UpdateOperation.UpdateAsync(...), который вызывает FindEntityByIdAsync(...) в качестве своего первого параметра, я заканчиваю как с новыми, так и со старыми дочерними объектами в БД. Например, если список содержал 2 элемента, а обновленный список также содержит 2 элемента (независимо от того, был ли он изменен или неизменен), в БД теперь 4 элемента, и запрос GET также возвращает 4 элемента. Что мне следует изменить, чтобы он работал с UpdateOperation?
Я попробовал вручную переключить EntityState на Modified, но это не сработало. Мне код кажется таким же, и я только переместил его в другое место, так что проблем быть не должно. Или я что-то упускаю?

Подробнее здесь: https://stackoverflow.com/questions/792 ... -db-and-at
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»