IsConcurrencyToken () не влияет на обновление - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь реализовать оптимистичный c параллелизм с использованием EF Core 2.1. У меня есть следующая конфигурация объекта для Site:

modelBuilder.Entity<Site>(entity =>
{
    entity.ToTable("Site", "Asset");
    entity.Property(e => e.ModifiedDate).HasColumnType("datetime")
          .IsConcurrencyToken();
    //rest omitted
});

Объект обновляется в обработчике MediatR:

public class EditCommandHandler : IRequestHandler<EditCommand, ReadCommand>
{
    private readonly ApplicationContext _db;
    private readonly IMapper _mapper;

    public EditCommandHandler(ApplicationContext db, IMapper mapper)
    {
        _db = db;
        _mapper = mapper;
    }

    public async Task<ReadCommand> Handle(EditCommand command, CancellationToken cancellationToken)
    {
        /**some validation**/

        var entity = await _db.Site.SingleOrDefaultAsync(x => x.CodePath == command.CodePath);

        //map from viewModel to Site entity
        _mapper.Map(command, entity); 

        entity.ModifiedDate = DateTime.UtcNow;
        _db.Site.Update(entity);

        //should throw exception here
        await _db.SaveChangesAsync(cancellationToken);

        /**load navigation Properties and return viewmodel. Logic omitted*/
        return site;
    }

Я ожидаю, что если я попытаюсь обновить объект, с другим ModifiedDate, чем тот, который извлекается из базы данных, что DbUpdateConcurrencyException выбрасывается, но это не так. Изменения успешно записываются в базу данных.

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

Почему проверка параллелизма не происходит? Что я тут не так сделал?

1 Ответ

0 голосов
/ 15 января 2020

Я решил это, хотя понятия не имею, почему это работает сейчас. Если у кого-то есть объяснение этому, я весь в ушах.

Первое, что я сделал после нескольких часов проб и ошибок, - это переключился на подход RowVersion, хотя я не смог объединить этот код в используй это. Он вел себя так же - версия строки была, по-видимому, проигнорирована.

Это привело меня на путь, чтобы явно установить исходные значения после того, как произошло сопоставление:

_mapper.Map(command, entity);
//for some reason that helps! ha!
_db.Entry(entity).OriginalValues["ModifiedDate"] = command.ModifiedDate;

entity.ModifiedDate = DateTime.UtcNow;
try
{
    await _db.SaveChangesAsync(cancellationToken);
}

Теперь это вызывает исключение Если RowVersion или атрибут, помеченный как параллелизм, не суммируются.

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

Теперь я перейду к написанию некоторых модульных тестов, убедившись, что никто другой случайно не сломает это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...