如何从LINQ调用标量值函数到实体服务器端

时间:2011-08-09 15:44:48

标签: entity-framework-4 linq-to-entities entity-framework-4.1 user-defined-functions

我的数据库中有一个标量值函数:

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来[字符串](System.String,   System.Data.Objects.ObjectParameter [])'方法,而这个方法不行   被翻译成商店表达。

其他信息:

这是在服务器上运行的所有查询的一部分 由于性能原因,返回所有数据并使用LINQ to Objects不是一种选择。

我不确定我的ExecuteFunction的返回类型是否正确,但我不确定它还能是什么...... 我做错了什么?

修改
在Ladislav Mrnka的回答的帮助下,这是解决方案:

创建公开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 个答案:

答案 0 :(得分:9)

您是否在EDMX中映射了您的功能?我猜你没有。

在设计器中运行从数据库更新向导,并在存储过程中选择要导入的SQL函数,并按照this article创建标有EdmFunctionAttribute的帮助方法以公开SQL LINQ-TO-Entities的函数。

注意:code-first / fluent-API不支持SQL函数。您需要使用EDMX映射。

ExecuteFunction用于调用EDMX中映射的要素 - 它需要映射要素的名称(存储过程的函数导入)。 MSDN说,它也可以调用映射函数,但我不知道如何 - 它调用函数导入和SQL函数导入没有任何。

答案 1 :(得分:0)

那么,您需要修改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.
  

标量函数 - &gt;转换为表值函数,它可以工作

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