Entity Framework: эквивалент INSERT ИЛИ IGNORE - PullRequest
1 голос
/ 18 июля 2009

Я использую базу данных в качестве своего рода кеша - цель состоит в том, чтобы хранить известные на данный момент "факты" (детали не так уж интересны). Крайне важно, однако, я хотел бы избежать вставки дублирующих фактов. Для этого текущий код доступа к данным во многих местах использует вставку или игнорирует.

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

Тем не менее, я не могу найти хорошую поддержку для добавления новых фактов - очевидный способ, по-видимому, состоит в том, чтобы просто создавать новые сущности в .NET, добавлять их в модель и сохранять изменения в базе данных. Тем не менее, это означает, что мне нужно заранее проверить, существует ли конкретная строка, так как вставка запрещена. В лучшие времена это означает дополнительные обходы, но обычно это намного хуже: раньше этот код был очень параллельным - случайная дублирующая вставка не имела бы значения, поскольку база данных просто игнорировала бы ее - но теперь мне не только нужно проверять, строка существует заранее, я должен был бы сделать это в гораздо меньших пакетах (которые обычно во много раз медленнее из-за накладных расходов транзакции), поскольку только одна уже существующая строка из параллельной вставки вызовет откат всей транзакции.

Итак, кто-нибудь знает, как получить похожее поведение, используя структуру сущностей?

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

Если это имеет значение, я использую SQLite.

1 Ответ

1 голос
/ 22 августа 2009

Эта функциональность может быть реализована с помощью хранимых процедур (которые может использовать инфраструктура сущностей) в тех БД, которые ее поддерживают (например, MSSQL). На SQLite это не поддерживается. Однако для sqlite также существует простое решение, а именно использование триггеров, таких как:

CREATE TRIGGER IF NOT EXISTS MyIgnoreTrigger BEFORE INSERT ON TheTable
FOR EACH ROW BEGIN 
   INSERT OR IGNORE 
      INTO TheTable (col1, col2, col3) 
      VALUES (NEW.col1, NEW.col2, NEW.col3);
   select RAISE(IGNORE);
END;

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

...