вызов хранимых процедур с помощью EF 4.0 и использование выходных параметров

#c# #.net #entity-framework-4

#c# #.net #entity-framework-4

Вопрос:

Допустим, у меня есть хранимая процедура GetAddressInfo(addressId int, errorCode int output) . Хранимая процедура возвращает адресную строку 1 и состояние, если addressId соответствует строке в базе данных. Если строка не найдена, то коду ошибки присваивается ненулевое значение, и оператор select не запускается. Итак, это будет выглядеть так:

 if (valid address id) begin
    Set errorCode = 1
    return
end

select AddressLine1, State from ....
  

Когда я использую EF 4.0 для вызова такой хранимой процедуры, я получаю исключение Entity Framework, когда address id оно недопустимо. В исключении упоминается, что столбец AddressLine1 не был частью средства чтения данных.

Я не ожидал никаких результатов (никаких записей), а для параметра кода ошибки вывода установлено значение 1. Вместо этого я получаю исключения. Я просто хочу прекратить обработку остальной части хранимой процедуры и немедленно вернуться. Похоже, что это не очень хорошо поддерживается EF 4.0.

Есть идеи по этому поводу?

Заранее спасибо!

Комментарии:

1. Эта проверка идентификатора адреса принадлежит вашему приложению …

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

Ответ №1:

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

EF обычно должен знать возвращаемые поля (в зависимости от того, как вы их сопоставили). Как конкретно вы вызываете эту процедуру? непосредственно в контексте или он сопоставляется с операцией объекта (например, операция выбора-чтения)

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

Комментарии:

1. Бизнес-логика и то, где она должна принадлежать, всегда являются горячей темой. Это существующий проект, который я пытался преобразовать с использованием уровня базы данных 3-й части в EF 4.0. У нас есть значительное количество sps, где присутствует эта логика. Теперь я понимаю, что EF 4.0 имеет тенденцию отображать все в объекты и ожидать согласованного вывода столбцов. Нам просто нужно будет постепенно отходить от этой логики sps и больше не использовать оператор ‘return’. Я где-то читал, что EF теперь очень хорошо работает с операторами ‘return’.

Ответ №2:

Почему бы вам не сделать проверку на наличие действительного адреса перед вызовом SP с помощью этого SP всегда будет возвращать действительное значение address, и это не вернет никаких исключений.

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

Ответ №3:

Ну, ваш подход немного странный — по крайней мере, для EF.

В некоторых случаях вы возвращаете AddressLine1 и State (поэтому он был настроен на ожидание этих двух), а в других — нет… таким образом, в зависимости от входных данных форма вашего вывода отличается. EF действительно не может с этим справиться…

Одним из простых способов решения этой проблемы было бы всегда возвращать эти два столбца — если addressId недопустимо, то просто возвращайте NULL для каждого столбца.

Комментарии:

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

Ответ №4:

Если в сообщении об исключении указано, что «столбец ‘AddressLine1’ не был частью средства чтения данных», то, похоже, функция вернулась без выполнения оператора select . Но, с другой стороны, вы пытаетесь прочитать значения считывателя данных, где вообще нет значений!!

Взгляните на эту подробную статью о том, как вызвать хранимую процедуру в EF с выходными параметрами. http://weblogs.asp.net/dwahlin/archive/2011/09/23/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters.aspx