从 Linq Query 调用 SQL 标量函数

Calling SQL scalar function from Linq Query

这里有很多类似的帖子,但是none个不能解决我的问题。

据我所知,有两种方法可以从 linq 调用 SQL 标量函数。

1。方法:

我已经使用 XML 编辑器将我的函数添加到 .edmx 文件,我的函数是:

<Function Name="prisustvoPostotci" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
  <CommandText>
    select dbo.prisustvoPostotci(@matica_ID,@godina)
  </CommandText>
  <Parameter Name="matica_ID" Type="int" Mode="In" />
  <Parameter Name="godina" Type="int" Mode="In" />
</Function>

我转到 model browser 并在 Function Imports 中双击我的函数 更改 return 集合类型为 Int32。我的函数是 returning integer.

现在我可以使用以下方法从 linq 调用我的函数:

using (DB_Entities dm = new DB_Entities())
{
  dm.prisustvoPostotci(1, 2016).FirstOrDefault();
}

它return是一个有效的整数值!

但是如果我像这样从 Linq Query 调用我的函数:

query = query.Where(x => x.date.Value.Year == max_year &&
                dm.prisustvoPostotci(x.ID, max_year).FirstOrDefault() >= 50);

它抛出这个错误:

LINQ to Entities does not recognize the method 'System.Data.Entity.Core.Objects.ObjectResult1[System.Nullable1[System.Int32]] prisustvoPostotci(System.Nullable1[System.Int32], System.Nullable1[System.Int32])' method, and this method cannot be translated into a store expression.

2。方法:

我已经使用 XML 编辑器将我的函数添加到 .edmx 文件,我的函数是:

<Function Name="prisustvoPostotci" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
  <CommandText>
    select dbo.prisustvoPostotci(@matica_ID,@godina)
  </CommandText>
  <Parameter Name="matica_ID" Type="int" Mode="In" />
  <Parameter Name="godina" Type="int" Mode="In" />
</Function>

我转到 model browser 并在 Function Imports 中双击我的函数 更改 return 集合类型为 Int32。我的函数是 returning integer.

然后我创建了一个部分class并写了这个方法:

public static class EntityFunctions
{
    [EdmFunction("Model.Store", "prisustvoPostotci")] 
    public static int prisustvoPostotci(int matica_ID, int godina) 
    {
        throw new NotSupportedException("Direct calls not supported"); 
    } 

}

"Model.Store" 是从 .edmx 文件中的模式命名空间中读取的模型商店的正确名称。

现在,如果我使用以下方法从 linq 调用我的函数:

EntityFunctions.prisustvoPostotci(119, 2016).ToString()

它抛出这个错误:

throw new NotSupportedException("Direct calls not supported");

此外,如果我像这样从 Linq Query 调用我的函数:

query = query.Where(x => x.date.Value.Year == max_year &&
                EntityFunctions.prisustvoPostotci(x.ID, max_year) >= 50);

它抛出这个错误:

The function or function import 'Model.Store.prisustvoPostotci' is not composable. A non-composable function or function import cannot be called in a query expression.

我试图编辑我的 .edmx 文件并更改 属性 IsComposable="true",但它给了我这个错误:

Functions declaring command text cannot be composed.

你能帮我解决这个问题吗!? 非常感谢!!

::干杯::

乔西普

感谢 Gerd Arnold,我意识到标量函数不能在查询 where 语句中使用。

以下是我如何通过在查询外调用标量函数来过滤我的查询:

var result = query.ToList();

for (int i = 0; i < result.Count; i++)
{
    // prisustvoPostotci(ID, year) is my scalar function
    if (dm.prisustvoPostotci(result[i].ID, max_year).FirstOrDefault() >= 50)
    {
        result.Remove(result[i]);
        i--;
    }
}   

这样调用标量函数就可以了,我们可以从结果中删除匹配的记录!

希望这会对某人有所帮助。

:: 欢呼::

约瑟普