Как вызвать скалярную функцию из LINQ для сущностей на стороне сервера - PullRequest
8 голосов
/ 09 августа 2011

В моей БД есть функция со скалярным значением:

ALTER FUNCTION [dbo].[fx_fooFunct]
  (@MyParam varchar(max))
RETURNS varchar(max)
AS
BEGIN
  return @MyParam
END

Я хочу вызвать эту функцию из запроса LINQ to Entities и получить результат в переменную:

let result = this.ObjectContext.ExecuteFunction<string>("SELECT dbo.fx_fooFunct(@MyParam)", new ObjectParameter("MyParam", "hello world")).FirstOrDefault()

Но, когда я выполняю код, я получаю эту ошибку:

LINQ to Entities не распознает метод 'System.Data.Objects.ObjectResult`1 [System.String] ExecuteFunction [String] (System.String, System.Data.Objects.ObjectParameter []) ', и этот метод нельзя преобразовать в выражение хранилища.

Другая информация:

Эточасть всего запроса, выполняемого на сервере.
Возврат всех данных и использование LINQ to Objects не вариант из-за производительности.

Я не уверен, что у меня есть тип возвратаExecuteFunction правильно, но я не уверен, что еще это может быть ... Что я делаю не так?

Редактировать
С помощью ответа Ладислава МрнкиВот решение:

Создать вспомогательный метод, предоставляющий функцию SQL:

public class CustomSqlFunctions
{
    [EdmFunction("MyModel.Store", "fx_fooFunct")]
    public static string FooFunct(string myParam)
    {
        throw new NotSupportedException("Direct calls not supported");
    }
} 

LINQ должен теперь читать:

let result = CustomSqlFunctions.FooFunct("hello world")

Ответы [ 2 ]

9 голосов
/ 09 августа 2011

У вас есть ваша функция, отображенная в EDMX?Наверное, нет.

Запуск Обновление из базы данных * Мастер 1004 * в конструкторе и в хранимых процедурах выберите функцию SQL для импорта и следуйте этой статье для создания помощникаметод, помеченный EdmFunctionAttribute для предоставления функции SQL для LINQ-TO-Entities.

Примечание: функции SQL не поддерживаются в code-first / fluent-API.Необходимо использовать сопоставление с EDMX.

ExecuteFunction используется для вызова функций, сопоставленных в EDMX - он ожидает имя сопоставленной функции (импорт функций хранимых процедур).MSDN говорит, что он также может вызывать сопоставленные функции, но я не знаю как - он вызывает импорт функций, а импорт функций SQL не имеет их.

0 голосов
/ 17 августа 2017

Что ж, вам нужно изменить SQL, чтобы преобразовать одиночное / скалярное значение в табличную функцию, тогда она будет работать.Поскольку пока нет поддержки скалярной функции https://social.msdn.microsoft.com/Forums/en-US/756865e5-ff25-4f5f-aad8-fed9d741c05d/add-scalar-function-to-function-import-folder-in-model-browser-of-entity-framework-40-edmx?forum=adodotnetentityframework

Скалярная функция, как она была, которая не работает

CREATE FUNCTION [dbo].[GetSha256]
(
    -- Add the parameters for the function here
    @str nvarchar(max)
)
RETURNS VARBINARY(32)
AS
BEGIN
    RETURN ( SELECT * FROM HASHBYTES('SHA2_256', @str) AS HASH256 );
END -- this doesn't work.

Скалярная функция-> Преобразована в табличную функцию, она работает

CREATE FUNCTION [dbo].[GetSha2561]
(
    -- Add the parameters for the function here
    @str nvarchar(max)
)
RETURNS  @returnList TABLE (CODE varbinary(32))
AS
BEGIN

    INSERT INTO @returnList
    SELECT HASHBYTES('SHA2_256', @str);

    RETURN; -- This one works like a charm.

END
...