Страницы

Поиск по вопросам

суббота, 22 июня 2019 г.

Как не допустить создания дубликатов в БД

Предположим есть следующий класс, который символизирует таблицу в БД:
public class Operation { public string Detail { get; set; } public string Number { get; set; } public int EquipmentId { get; set; } }
При создании пользователем данной сущности необходимо информировать о попытке создания дубликата.
Дубликатом считается наличие объекта в бд с такими же значениями приведенных полей
Как это можно сделать?


Ответ

Наиболее предпочтительным является способ проверки на дубликат средствами самой бд.
В Entity Framework это может выглядеть например так:
воспользуемся средствами fluent api
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .Property(x => x.Detail) .IsRequired() .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_Operation", 1) { IsUnique = true })); modelBuilder.Entity() .Property(x => x.Number) .IsRequired() .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_Operation", 2) { IsUnique = true })); modelBuilder.Entity() .Property(x => x.EquipmentId) .IsRequired() .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_Operation", 3) { IsUnique = true })); }
При помощи атрибута Index
public class Operation { [Index("IX_Operation", 1)] public string Detail { get; set; } [Index("IX_Operation", 2)] public string Number { get; set; } [Index("IX_Operation", 3)] public int EquipmentId { get; set; } }
будет создан индекс на основании необходимых полей и попытка вставить дубликат выкинет исключение.
Использовать это необходимо так: Метод добавляющий запись в бд должен быть обернут в блок try
try { _operationService.Add(operation); } catch(Exception ex) { //Здесь обрабатываем возникшее исключение }
если же возможность изменить структуру таблицы есть но в бд уже есть дубликаты, то тогда необходимо сначала избавиться от дубликатов и потом создать индекс.
Если же по какой либо причине изменить бд(создать необходимый индекс) невозможно то тогда можно делать проверку перед вставкой в бд, но стоит помнить что такой вариант является менее эффективным(исключение составляет когда с бд работает один пользователь), так как после проверки и перед вставкой другой пользователь может добавить запись, выглядеть это может например так:
public static bool OperationIsExist(this IQueryable src, Operation operation) { return src .Where(x=>x.Detail.Equals(operation.Detail, StringComparison.InvariantCultureIgnoreCase)) .Where(x=>x.Number.Equals(operation.Number, StringComparison.InvariantCultureIgnoreCase)) .Where(x=>x.EquipmentId==operation.EquipmentId) .Any(); }

Комментариев нет:

Отправить комментарий