Entity Core: Перед записью проверить данные на уникальность31.10.2018, 13:21. Показов 13695. Ответов 29
Метки entity framework (Все метки)
Добрый день.
Столкнулся с проблемой - хочу чтобы в таблице были только уникальные значения. Решил проверять нет ли уже такой записи в таблице. Для проверки написал расширения для класса Db. В моей БД 4 таблицы - в две из них пишу всё подряд, а в две другие - только то, чего там еще нет. (Все четыре модели у меня реализуют пустой интерфейс IDbData. Поэтому приходится в условном операторе определять тип переданного объекта.) Вот код:
Пошаговый дебаг не прояснил ситуацию. Возможно я не верно понимаю принцип работы EntityFramework? Я решил проверять объекты на равенство друг другу:
И вообще насколько это корректно? Может быть у Entity есть какой-то свой способ? Заранее спасибо.
0
|
|||||||||||
| 31.10.2018, 13:21 | |
|
Ответы с готовыми решениями:
29
Как проверить ID записи на уникальность перед занесением в базу данных? проверить pipe перед записью Перед записью проверить существование или пустоту файла |
| 06.11.2018, 16:39 [ТС] | |||
|
Вы мне тогда ответили: Поправьте меня, если я не прав, но кажется мы ходим по кругу.
0
|
|||
|
14368 / 9469 / 1360
Регистрация: 21.01.2016
Сообщений: 35,733
|
|
| 06.11.2018, 16:43 | |
|
skitale, нет. Я вам предлагаю не просто самому в коде проверку делать, но делать это внутри транзакции, а на полях требующих уникальности должны висеть индексы уникальности. Это сильно не тоже самое.
0
|
|
|
14368 / 9469 / 1360
Регистрация: 21.01.2016
Сообщений: 35,733
|
|
| 06.11.2018, 17:03 | |
|
skitale, разница в словах выделенных жирным текстом. Индекс уникальности ускорит (в десятки раз) поиск по полям с ним, а уникальность защитит поле от неуникального значения на уровне СУБД (если в коде ошибётесь). Транзакция заблокирует доступ к индексу параллельным транзакциям, что защитит данные на время выполнения текущей транзакции (параллельно никто не сможет запихнуть данные, чью уникальность вы только что проверили, но запись в базу ещё не совершили).
Ну и если такой подход покажет плохую производительность (и только в этом случае), то можно прибегнуть к чистому SQL.
0
|
|
| 06.11.2018, 17:41 [ТС] | |||||||
|
Код ниже выдает ту же ошибку:
Usaga, хоть убейте я не могу понять как предложенный вами вариант решает заявленную в теме проблему. Индекс ускоряет поиск - прекрасно, но у меня не было проблем со скоростью поиска. Использование транзакции предотвращает параллельную запись в базу - очень хорошо, но я пишу в базу синхронно в один поток. От кого блокировать базу? Прежде вы говорили, что СУБД сама проверит данные на уникальность с помощью индекса - да, она проверяет, но EF не знает что с этим делать дальше и из 1500 записей записывает 12, натыкается на ошибку СУБД и дальше не пишет вообще ничего. По-моему в этом проблема, а не в скорости работы или взаимной блокировке. Вы уже предлагали делать "неправославно": Пусть долго и неэффективно, но чтобы оно заработало в конце-концов.
0
|
|||||||
|
14368 / 9469 / 1360
Регистрация: 21.01.2016
Сообщений: 35,733
|
||||||||
| 06.11.2018, 17:56 | ||||||||
|
skitale, код отвратителен чуть более, чем полностью.
Ещё и работает он задомнаперёд: он только дубликаты пытается записать.Если сохранить авторский стиль, то так должно быть чуть лучше: Кликните здесь для просмотра всего текста
0
|
||||||||
| 06.11.2018, 18:16 [ТС] | ||||
|
0
|
||||
|
14368 / 9469 / 1360
Регистрация: 21.01.2016
Сообщений: 35,733
|
||||||||
| 07.11.2018, 06:16 | ||||||||
|
Ошибка на этапе компиляции? Если да, то каков её текст? Исключение во время работы? Если да, то на какой строке, каково название исключения и текст из его свойства Message? Код молча отрабатывает, но делает не то, что нужно? Пройдите по коду под отладчиком (debugger) шаг за шагом и посмотрите, что на самом деле делает ваш код. * метод в параметрах принимает конкретный тип List<T>, хотя использует только возможности реализуемого им интерфейса IEnumerable<T>. Принимайте в параметрах настолько общие интерфейсы\классы, насколько это возможно.* принимаемая в параметрах коллекция содержит объекты какого-то сильно общего интерфейса IDbData, реальный тип которого вы довольно кривым образом проверяете, а потом кастуете к нужному типу. В 99.9% случаев можно было сделать нормально и передавать коллекцию нужных объектов, без проверок и кастования.* класс контекста (Db) назван безобразно. Давайте классам говорящие имена, отражающие их суть и назначение. * Db создаётся прямо в методе. Такое допустимо только в совсем крохотных приложениях. В остальных случаях Db желательно завернуть в репозиторий (паттерн такой) и принимать в конструкторе класса, в методе которого это дело и используется. Иначе формируется очень жёсткая связь между классами.* метод SendToDb пишет прямо в консоль. Это фу ещё хуже, чем в пункте выше. Заведите интерфейс ILogger (название на усмотрение), реализация которого и будет писать куда вам надо. Внедряйте Logger или через IoC (желательно) или через синглтон (сильно проще, чем IoC, приемлемо в небольших проектах).* кодом вида
null тут бесполезна.* вы на каждой итерации цикла создаёте новую транзакцию и совершаете запись в базу. Если записей не миллионы, то сильно быстрее было бы (в плане скорости работы с базой) завести одну транзакцию на весь цикл и по окончанию цикла, сохранить изменения (разом) и завершить транзакцию.
1
|
||||||||
| 07.11.2018, 13:38 [ТС] | ||
|
Usaga, огромное спасибо за развернутый ответ! Многое не понял, так что ушел читать матчасть
![]() Добавлено через 5 минут
0
|
||
|
14368 / 9469 / 1360
Регистрация: 21.01.2016
Сообщений: 35,733
|
|
| 07.11.2018, 14:17 | |
|
0
|
|
| 07.11.2018, 14:17 | |
|
Проверить данные перед обновлением
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
|
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
|
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения.
https:/ / habr. com/ ru/ sandbox/ 295048/
начало и оглавление
-
Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
|
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
|
|
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано
Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
|
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано
Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
|
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0)
Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона
Уважаемые коллеги!
В продолжение. . .
|
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии
Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
|