Проблема с добавлением данных в БД

112
12 сентября 2019, 06:20

Есть таблица Image. В ней есть несколько полей (интересуют id ImageName, они должны быть равны).

Щас так:

Images img = new Images
{
    ImageName = (_productContext.Images.Count() > 0 ? (Convert.ToInt32(await _productContext.Images.MaxAsync(x => x.Id)) + 1).ToString() : "0")
};
await _productContext.Images.AddAsync(img)

но это очень криво. Как правильно прировнять инкрименту до сохранения в БД??? Может как то можно сделать с другой стороны: например при уделении элемента в MySql если есть id 1,2,3 , удалить 3, а потом добавить один элемент, то добавить 4, получается что 3 пропускается (может как то можно это обойти?)

Answer 1

мне нужно чтобы ImageName было такое же как и id всегда

Не стоит так делать. Во-первых, id может поменяться. Например, при переходе на другую СУБД, или при слиянии данных из разных БД, или при изменении схемы. Поэтому привязывать id, предназначенный для работы движка СУБД к полю, предназначенному для просмотра человеком, не следует.

Во-вторых, ваш код легко нарвётся на проблемы, если к БД обращаются несколько клиентов (или потоков). Например, вы получаете значение с помощью MaxAsync, потом другой клиент/поток добавляет строку в таблицу, после чего ваше значение устаревает и становится неверным.

Что можно сделать, оставаясь в рамках EF?

Сперва объект без поля ImageName записать в БД, потом получить Id, сгенерированный для этого объекта и обновить ImageName. Примерно, так:

Images img = new Images();
await _productContext.Images.AddAsync(img);
await _productContext.SaveChangesAsync();
img.ImageName = img.Id.ToString();
await _productContext.Images.UpdateAsync(img);
await _productContext.SaveChangesAsync();

На возражение, что при этом делаются несколько запросов в БД (insert и update - итого два), есть простой ответ: приведённый в вопросе код тоже делает несколько запросов: Count (кстати, его следовало бы заменить на CountAsync), MaxAsync, AddAsync - итого три.

Возможны подходы без строгой опоры на Entity Framework.

Использовать триггер в БД. Этот триггер при вставке будет задавать значение для ImageName.

Ещё можно сделать поле ImageName вычисляемым. Оно вообще не хранится, а вычисляется на лету.

А вообще, раз уж значение всё равно генерируется автоматически, то можно генерировать его на клиенте. Например, использовать GUID.

READ ALSO
Нужна помощь с паркингом из vk (не api)

Нужна помощь с паркингом из vk (не api)

Мне нужно получить все id страниц пользователе с заданным именем и фамилиейОднако Vk api выдает только первые 1000 страниц Условно, если "Павел...

147
xamarin forms Alarm Manager

xamarin forms Alarm Manager

Как сделать пуш уведомления по расписаниюНапример, каждый день в 10

107
В каком пакете в nuget находится @inject?

В каком пакете в nuget находится @inject?

Использую aspnet framework, для отображения авторизованного пользователя хочу сделать как тут, чтобы можно было передавать дополнительную инфу...

93
Не могу создать правильный класс для серилизации Json

Не могу создать правильный класс для серилизации Json

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

100