Entity Framework 4 Функция импорта не работает

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

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

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

Я делаю что-то неправильно?


person dotariel    schedule 29.09.2010    source источник


Ответы (2)


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

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

Я могу придумать три способа решить вашу проблему:

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

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

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

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

person grahamesd    schedule 18.11.2010

При исследовании файла 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 и, следовательно, доступные через Интеллисенс.

person Mark_Gibson    schedule 02.11.2011