Entity Framework 4 Функция импорта не работает - PullRequest
5 голосов
/ 30 сентября 2010

Я использую Entity Framework 4 с генератором кода POCO. У меня есть хранимая процедура, которая выполняет INSERT и возвращает @@ IDENTITY вставленной записи. Я пытаюсь импортировать хранимую процедуру как функцию в моем файле .edmx, но у меня возникают проблемы с ее использованием.

В браузере модели я могу увидеть хранимую процедуру под иерархией базы данных, а затем щелкнуть правой кнопкой мыши и выбрать «Импорт функции ...». Я попытался использовать «Нет» в качестве типа возврата, а также Int32 ( хотя там написано "Сборник .."). Функция появляется в разделе «Импорт функций», но даже после сохранения и компиляции я не могу найти функцию где-либо в моем ObjectContext. Я пытался удалить его и повторно импортировать хранимую процедуру несколько раз, но безуспешно.

ПРИМЕЧАНИЕ. У меня есть другая хранимая процедура, которая выполняет прямой SELECT, и она импортирована правильно и отображается в коде ObjectContext.

Я что-то не так делаю?

Ответы [ 2 ]

5 голосов
/ 02 ноября 2011

При исследовании файла POCO .Context.tt я нашел следующий код в строке 111

if (edmFunction.ReturnParameter == null)
{
    continue;
}
string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));

, что означает, что любая функция импорта, которая возвращает 'none', не будет записана.

Я изменил свой файл .Context.tt так, чтобы приведенный выше код был заменен на

string returnTypeElement = @"";
if (edmFunction.ReturnParameter == null)
{
    returnTypeElement = @"void";
} else {
    returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
}

Затем мне пришлось добавить несколько проверок вокруг объявления функции (около строки 118)

<#
    if(returnTypeElement != "void"){
#>
    <#=Accessibility.ForMethod(edmFunction)#> ObjectResult<<#=returnTypeElement#>>   <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#  
    } else {
#>
    <#=Accessibility.ForMethod(edmFunction)#> <#=returnTypeElement#> <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#  
    } 
#>

и оператор возврата (около строки 142)

<#
    if(returnTypeElement != "void"){
#>
        return base.ExecuteFunction<<#=returnTypeElement#>>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#  
    } else {
#>
        base.ExecuteFunction("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#  
    } 
#>  

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

5 голосов
/ 18 ноября 2010

Если ваша хранимая процедура не возвращает результирующий набор, поэтому вы выбираете «Возвращает коллекцию» «Нет» в диалоговом окне «Добавление импорта функций» в Visual Studio, то импорт функции НЕ добавляется в качестве метода в сгенерированный объектный контекст. (Я пока не смог выяснить, почему, но я все еще ищу.)

Возвращаемое значение из sproc (например, return @@ identity) - это не то, что подразумевается под вопросом «Возвращает коллекцию». Вот почему это не сработало. Вопрос в том, какой набор результатов возвращается из sproc.

Есть три способа решения вашей проблемы:

  1. Верните значение вашей идентичности с помощью выбора (например, выберите @@ identity в качестве Identity), а затем укажите коллекцию Int32 в ответ на вопрос «Возвращает коллекцию».

  2. Верните значение вашей идентичности, используя предложение output в вашем операторе вставки, и получите его так же, как в 1.

  3. Используйте Entity SQL и сделайте значение идентификатора выходным параметром. Вот как это сделать: Как: выполнить запрос, используя хранимую процедуру с параметрами In и Out

Надеюсь, это поможет.

...