8

Tengo una función escalar de valor en mi DB:Cómo llamar función con valores escalares de LINQ a Entidades del lado del servidor

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

Quiero llamar a esta función desde un LINQ a Entidades consulta y obtener la resultar en una variable:

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

embargo, cuando ejecuto el código, me sale este error:

LINQ to Entities does not recognize the method 'System.Data.Objects.ObjectResult`1[System.String] ExecuteFunction[String](System.String, System.Data.Objects.ObjectParameter[])' method, and this method cannot be translated into a store expression.

Otro yo nfo:

Esto es parte de una consulta que se ejecuta en el servidor.
Devolver todos los datos y usar LINQ to Objects no es una opción debido al rendimiento.

no estoy seguro de que tengo el tipo de retorno de la ExecuteFunction correcta, pero no estoy seguro de qué más podría ser ... ¿qué estoy haciendo mal?

Editar
Con la ayuda de la respuesta de Ladislav Mrnka, aquí está la solución:

Crear método de ayuda exponer la función SQL:

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

El LINQ ahora será la siguiente:

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

Respuesta

9

¿Tiene su función mapeada en EDMX? Supongo que no.

Run actualización de la base de datos del asistente en el diseñador y con los procedimientos almacenados seleccionar la función SQL para importar y seguir this article para crear método de ayuda marcados con EdmFunctionAttribute para exponer la función de SQL para LINQ a Entidades.

Nota: las funciones de SQL no son compatibles en code-first/fluent-API. Necesita usar el mapeo con EDMX.

ExecuteFunction se usa para llamar a las funciones mapeadas en EDMX - espera el nombre de la función mapeada (función de importación de procedimientos almacenados). MSDN dice que también puede llamar a las funciones mapeadas, pero no sé cómo: llama a la importación de funciones y la importación de funciones SQL no tiene ninguna.

+0

Excelente, muchas gracias. He actualizado mi pregunta con la solución. – mcqwerty

0

Bueno, necesita modificar SQL para convertir el valor único/escalar a la función de tabla de valores, entonces funcionará. Como no hay soporte para la función con valores escalares todavía 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

Scalar function as it was, which doesn't work

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. 

Scalar function -> Converted to Table Valued function , it works

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 
Cuestiones relacionadas