#c# #.net #sql-server #stored-procedures #entity-framework-4
#c# #.net #sql-сервер #хранимые процедуры #entity-framework-4
Вопрос:
Я сгенерировал модель Entity Framework из базы данных SQL Server 2005 и начал импортировать хранимые процедуры. Пока все хорошо, но одна из хранимых процедур выдает исключение, когда я пытаюсь ее запустить:
Процедура или функция ‘csp_getCoworker’ ожидает параметр ‘@@firstname’, который не был предоставлен.
Вот подпись для хранимой процедуры:
ALTER PROCEDURE [dbo].[csp_getCoworker](
@@firstname nvarchar(32),
@@lastname nvarchar(32),
@@businessarea nvarchar(512),
@@location nvarchar(512)
)
И вот код, сгенерированный Entity Framework
ObjectParameter p_firstnameParameter;
if (p_firstname != null)
{
p_firstnameParameter = new ObjectParameter("p_firstname", p_firstname);
}
else
{
p_firstnameParameter = new ObjectParameter("p_firstname", typeof(global::System.String));
}
[...]
return base.ExecuteFunction<csp_getCoworker_Result2>("csp_getCoworker", p_firstnameParameter, p_lastnameParameter, p_businessareaParameter, p_locationParameter);
Это двойные символы @ в имени параметра, которые все портят?
Ответ №1:
Я только что протестировал это, потому что это очень необычный сценарий.
Хранимая процедура следует очень странному соглашению об именовании, потому что @@ не следует использовать. По умолчанию используется некоторыми системными переменными SQL Server и не должен использоваться ни для чего другого. Использование @x
в качестве параметра хранимой процедуры определяет параметр, x
но использование @@x
определит параметр @x
— @ является частью имени параметра!
Это очень большая проблема в C #, потому что @ — это escape-символ, используемый для определения имен переменных, таких же, как зарезервированные ключевые слова. Например:
string @string = "abc";
определяет переменную с именем string
. Имя переменной не может начинаться с @.
Entity Framework решает эту проблему, заменяя все @
на _
и добавляя префикс имени параметра на p
непосредственно в SSDL. Причина в том, что функция импорта, созданная из отображенной в SSDL хранимой процедуры, должна иметь параметры с тем же именем, что и процедура, но в то же время начальный символ @ недопустим. Если вы попытаетесь изменить EDMX вручную, он не выполнит собственную проверку XSD, потому что @ не разрешен начальный символ для идентификаторов, определенных в CSDL.
Даже это, вероятно, можно рассматривать как ошибку, это больше связано с отсутствием возможности изменить имя параметра в CSDL. На данный момент это сделано специально, и единственным способом является исправление имен параметров в хранимой процедуре SQL.
Комментарии:
1. Это был отличный ответ! Это дало мне толчок в правильном направлении, и я решил проблему, написав процедуры-оболочки с правильно названными переменными, которые просто передавали их соответствующему SP.
2. @Bartek: Что вам следовало сделать, так это найти того, кто решил, что было хорошей идеей использовать двойные знаки @ в именах своих параметров, дать им пощечину, а затем заставить их это исправить.
3. @Matti: Я пробовал это, но с тех пор они давно покинули организацию. >:(