Entity Core: Перед записью проверить данные на уникальность31.10.2018, 13:21. Показов 13781. Ответов 29
Метки entity framework (Все метки)
Добрый день.
Столкнулся с проблемой - хочу чтобы в таблице были только уникальные значения. Решил проверять нет ли уже такой записи в таблице. Для проверки написал расширения для класса Db. В моей БД 4 таблицы - в две из них пишу всё подряд, а в две другие - только то, чего там еще нет. (Все четыре модели у меня реализуют пустой интерфейс IDbData. Поэтому приходится в условном операторе определять тип переданного объекта.) Вот код:
Пошаговый дебаг не прояснил ситуацию. Возможно я не верно понимаю принцип работы EntityFramework? Я решил проверять объекты на равенство друг другу:
И вообще насколько это корректно? Может быть у Entity есть какой-то свой способ? Заранее спасибо.
0
|
|||||||||||
| 31.10.2018, 13:21 | |
|
Ответы с готовыми решениями:
29
Как проверить ID записи на уникальность перед занесением в базу данных? проверить pipe перед записью Перед записью проверить существование или пустоту файла |
| 06.11.2018, 16:39 [ТС] | |||
|
Вы мне тогда ответили: Поправьте меня, если я не прав, но кажется мы ходим по кругу.
0
|
|||
|
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
|
|
| 06.11.2018, 16:43 | |
|
skitale, нет. Я вам предлагаю не просто самому в коде проверку делать, но делать это внутри транзакции, а на полях требующих уникальности должны висеть индексы уникальности. Это сильно не тоже самое.
0
|
|
|
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
|
|
| 06.11.2018, 17:03 | |
|
skitale, разница в словах выделенных жирным текстом. Индекс уникальности ускорит (в десятки раз) поиск по полям с ним, а уникальность защитит поле от неуникального значения на уровне СУБД (если в коде ошибётесь). Транзакция заблокирует доступ к индексу параллельным транзакциям, что защитит данные на время выполнения текущей транзакции (параллельно никто не сможет запихнуть данные, чью уникальность вы только что проверили, но запись в базу ещё не совершили).
Ну и если такой подход покажет плохую производительность (и только в этом случае), то можно прибегнуть к чистому SQL.
0
|
|
| 06.11.2018, 17:41 [ТС] | |||||||
|
Код ниже выдает ту же ошибку:
Usaga, хоть убейте я не могу понять как предложенный вами вариант решает заявленную в теме проблему. Индекс ускоряет поиск - прекрасно, но у меня не было проблем со скоростью поиска. Использование транзакции предотвращает параллельную запись в базу - очень хорошо, но я пишу в базу синхронно в один поток. От кого блокировать базу? Прежде вы говорили, что СУБД сама проверит данные на уникальность с помощью индекса - да, она проверяет, но EF не знает что с этим делать дальше и из 1500 записей записывает 12, натыкается на ошибку СУБД и дальше не пишет вообще ничего. По-моему в этом проблема, а не в скорости работы или взаимной блокировке. Вы уже предлагали делать "неправославно": Пусть долго и неэффективно, но чтобы оно заработало в конце-концов.
0
|
|||||||
|
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
|
||||||||
| 06.11.2018, 17:56 | ||||||||
|
skitale, код отвратителен чуть более, чем полностью.
Ещё и работает он задомнаперёд: он только дубликаты пытается записать.Если сохранить авторский стиль, то так должно быть чуть лучше: Кликните здесь для просмотра всего текста
0
|
||||||||
| 06.11.2018, 18:16 [ТС] | ||||
|
0
|
||||
|
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
|
||||||||
| 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
|
||
|
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
|
|
| 07.11.2018, 14:17 | |
|
0
|
|
| 07.11.2018, 14:17 | |
|
Проверить данные перед обновлением
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
|
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
|
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства.
Жизнь действительно предъявляет каждому. . .
|
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
|
|
Лето уходит
kumehtar 17.08.2026
|
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
|
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины".
За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html
Задача: . . .
|
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
|