Entity Framework должна проверять повторяющиеся записи на основе уникального набора значений для нескольких столбцов, а затем добавлять новую запись.

У меня есть сценарий, в котором несколько вызовов API запускаются от разных клиентов через некоторый API (иногда через WebJob), в результате чего код API запускается одновременно. Этот код API вставляет записи в SQL через Entity Framework. Из-за одновременных вызовов таблица позволяет вставлять повторяющиеся записи, даже если есть условие для проверки существующей записи. Это происходит, когда разница между двумя вызовами составляет всего доли секунды.

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

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

В приведенном ниже примере будет рассмотрена проблема:

Записи в красной рамке не должны быть разрешены, если CategoryId и CategoryTypeid одинаковы и оба активны.

Записи в зеленой рамке должны быть разрешены. Поэтому, если есть несколько записей с одинаковыми CategoryId и CategoryTypeId, только одна из них должна быть активной.

Пожалуйста, помогите в какой-то идее, как разработать решение, чтобы исправить это в конце БД.

Пример дублированной записи


person swati gupta    schedule 26.10.2018    source источник
comment
Зачем вам хранить повторяющиеся строки неактивных записей? Кажется, это еще одно ключевое поле, такое как метка времени.   -  person serge    schedule 26.10.2018
comment
Неактивные записи сохраняются для целей аудита. Данные предназначены для мягкого удаления. Сначала я думал о перемещении этих записей в отдельную таблицу аудита, но в данный момент не могу позволить себе все эти изменения. Значит, пока с этим жить.   -  person swati gupta    schedule 27.10.2018


Ответы (3)


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

И в чем здесь проблема?

Определите 2 индекса.

1 уникальный индекс с CatergoryId, CategoryTypeId, IsActive = 1 в качестве фильтра 1 неуникальный индекс CatergoryId, CategoryTypeId, IsActive = 0 в качестве фильтра

Сделанный.

Фильтры — это малоизвестный факт об индексах, который большинство людей упускают из виду.

ЕДИНСТВЕННЫЙ способ ГАРАНТИРОВАТЬ это.

person TomTom    schedule 26.10.2018
comment
Я не знал, можно ли этого добиться с помощью фильтра/индексов. Не могли бы вы также пояснить, как этого добиться с помощью шагов со скриншотами/любым сложным способом установить это на уровне таблицы. Требуется ли для этого команда изменения таблицы. Если да, следует ли сначала обрезать таблицу перед применением этого? - person swati gupta; 27.10.2018
comment
Конечно я могу. 90€ в час. Это сайт вопросов и ответов, я не собираюсь предоставлять вам подробные инструкции, включая скриншоты бесплатно. Есть мануал, знаете ли. ИСПОЛЬЗУЙ ЭТО. Я дал вам достаточно подсказок, чтобы найти соответствующие части. - person TomTom; 27.10.2018
comment
Только что сэкономил 90 € :) Нашел решение, сохранив ваши подсказки в качестве справочного материала и прочитав множество статей. Размещение реализации решения здесь. Большое спасибо, что направили меня в правильном направлении!! Это действительно помогло. - person swati gupta; 27.10.2018

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

 select distinct categoryID,categoryTypeID,IsActive from Table where IsActive=1
 union all
 select categoryID,CategoryTypeID,IsActive from Table where IsActive=0

это может помочь вам.

person Halil İbrahim    schedule 26.10.2018
comment
Запрос не касается извлечения записей для чтения, таблица должна быть спроектирована таким образом, чтобы поддерживать требуемое ограничение, чтобы в любой момент времени можно было вставить только одну активную запись. - person swati gupta; 27.10.2018

Под руководством @TomTom я решил эту проблему с помощью приведенных ниже операторов SQL.

Создал два некластеризованных индекса в таблице и попытался повторно вставить дубликаты и получил соответствующую ошибку. Создание этих индексов гарантирует, что в таблице может существовать только одна активная запись.

--add unique nonclustered filtered index that allows only one active record
CREATE UNIQUE NONCLUSTERED INDEX unique_active_projects
ON TestDuplicates(CategoryId,CategoryTypeId,IsActive)
WHERE IsActive = 1
GO

--add non-unique nonclustered filtered index to allow multiple non-active records
CREATE NONCLUSTERED INDEX nonunique_inactive_projects
ON TestDuplicates(CategoryId,CategoryTypeId,IsActive)
WHERE IsActive = 0
GO

Надеюсь, это поможет кому-то с похожей проблемой!

person swati gupta    schedule 27.10.2018