Имена параметров хранимых процедур и Entity Framework

#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: Я пробовал это, но с тех пор они давно покинули организацию. >:(