@Di-Roll

Как сделать маппинг хранимых процедур в Entity Framework?

Для взаимодействия с базой данных используются должны использоваться хранимые процедуры, доступа к таблицам нет.
Используя метод MapToStoredProcedures я настраиваю DbSet'ы на использование хранимых процедур для вставки, обновления и удаления данных.
А как быть с выборкой?
Можно использовать Context.Database.SqlQuery для выполнения хранимой процедуры на выборку данных,
но тогда возникает ошибка при удалении записи (приходится использовать метод Attach):
Context.Table.Attach(item);
Context.Table.Remove(item);
  • Вопрос задан
  • 302 просмотра
Решения вопроса 1
DarkRaven
@DarkRaven
разработка программного обеспечения
Для выборки я бы посоветовал мапить на table-values functions, т.к. они при выборки оптимизируются (к примеру, если после вызова в .NET примените where), в отличие от процедур, которые вытаскивают всю выборку. Опять же, такой вариант позволит вам работать с ними как с IQueryable, что является несомненным плюсом.

Если у вас EDMX, то эти функции замапятся автоматически мастером. Если Code First, то вам нужен https://github.com/moozzyk/CodeFirstFunctions, Nuget пакет называется EntityFramework.CodeFirstStoreFunctions.

Мы использовали (и используем данный подход) с 2013 года - за это время проблем с ним не было. Еще момент, это работает только для MSSQL, если что-то другое используете, то этот вариант не подойдет.

К примеру, в моей случае, БД внезапно стала PostgreSQL, и я сделал немного по-другому. Выборку замапил на представление, где сделал умножение JOIN-ов, чтобы получить всевозможные варианты (в моем случае это связка сущность-ресурсы-язык_ресурса:

CREATE OR REPLACE VIEW public.v_companies AS 
 SELECT c.id,
    c.isdeleted,
    c.hversion,
    c.modifydate,
    c.modifierid,
    l.id AS languageid,
        CASE
            WHEN cr.id IS NOT NULL THEN cr.name
            ELSE cr_fb.name
        END AS name
   FROM companies c
     JOIN languages l ON true --- тада!
     LEFT JOIN company_resources cr ON c.id = cr.companyid AND cr.languageid = l.id
     LEFT JOIN company_resources cr_fb ON c.id = cr_fb.companyid AND cr_fb.languageid = (( SELECT crx.languageid
           FROM company_resources crx
          WHERE c.id = crx.companyid
         LIMIT 1))
  ORDER BY c.id, (
        CASE
            WHEN cr.name IS NOT NULL THEN 0
            ELSE 1
        END)


И сделал extension-метод для получения модели данного View, куда я отдавал CurrentLanguageId и делал по нему фильтрацию.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы