- Сначала я создал свою БД SQLite со всеми таблицами в ней
- Затем я сгенерировал классы DbContext и Model (для таблиц) с помощью команды Scaffold-DbContext из консоли диспетчера пакетов
- Я использовал столбец для метки времени и создал триггеры SQLite для его обновления после операций вставки и обновления. Столбец DATETIME фактически создается как TEXT в SQLite, но здесь проблема не в этом
- В классе модели I для соответствующего свойства (для столбца DATETIME) добавлены атрибуты
[ConcurrencyCheck]
и [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
- Теперь, тестируя мои операции CRUD через мои ASP.Net Core RazorPages, я открыл одну вкладку (браузер) для редактирования, а другую - для удаления
- Я изменяю содержимое строки на странице редактирования и сохраняю ее - работает как положено
- Теперь я перехожу на уже открытую страницу удаления (отображаемое содержимое устарело, поскольку оно было изменено прямо на странице редактирования) и пытаюсь удалить ее
- Запись успешно удалена, тогда как я ожидал исключения для параллелизма
Почему это так? Я что-то упустил? Заранее спасибо за любую помощь / предложения. Кстати, я использую Visual Studio 2017 Community 15.6.7 (последняя версия) в Windows 10 Pro x64 Build 1709 (с последними обновлениями) и .Net Core 2.1.104
С уважением,
Vatsan
Дополнительная информация из моего кода
Класс модели моего стола:
[Table("Client_Tags")]
public partial class ClientTags
{
[Key]
[Column("ID")]
[Display(Name = "Row ID")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required]
[Column("Client_ID", TypeName = "VARCHAR(255)")]
[Display(Name = "Client ID")]
public string ClientId { get; set; }
[Required]
[Column("Tag_Name", TypeName = "VARCHAR(255)")]
[Display(Name = "Tag")]
public string TagName { get; set; }
[Column("Last_Updated", TypeName = "DATETIME")]
[Display(Name = "Last Updated Time")]
[ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string LastUpdated { get; set; }
}
Фрагмент из моего метода DbContext.OnModelCreating ():
modelBuilder.Entity<ClientTags>(entity =>
{
entity.HasIndex(e => new { e.ClientId, e.TagName })
.IsUnique();
});
Фрагмент из моего Delete.cshtml:
<form method="post">
<input type="hidden" asp-for="ClientTag.Id" />
<input type="hidden" asp-for="ClientTag.LastUpdated" />"
<input type="submit" value="Delete" class="btn btn-default" /> |
<a asp-page="./Index">Back to List</a>
</form>
Фрагмент из моего Delete.cshtml.cs:
public async Task<IActionResult> OnPostAsync(long? id)
{
if (id == null)
{
return NotFound();
}
ErrMsg throwErrMsg = () =>
{
ModelState.AddModelError(
string.Empty,
"Error updating the values. Try again later"
);
return Page();
};
ClientTag = await _context.ClientTags.FindAsync(id);
if (ClientTag == null)
{
return throwErrMsg();
}
try
{
_context.ClientTags.Remove(ClientTag);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException e)
{
return throwErrMsg();
}
return RedirectToPage("./Index");
}
-х-х-х