C# HasDbFunction未将CLR函数映射到SQL Server函数

C# HasDbFunction未将CLR函数映射到SQL Server函数,c#,sql-server-2016,ef-core-5.0,C#,Sql Server 2016,Ef Core 5.0,我想在SQLServer中创建MyDbFunction标量函数,并使用HasDbFunction映射从.NET5应用程序调用它。由于某些原因,映射总是被忽略。我简化了我的示例,以确保它不是签名/参数问题,但这没有帮助。我按照官方文档构建了它: 第一步。 我创建了这个CLR函数: public int MyCLRFunction (int @Code) => throw new NotSupportedException("Mapping issue for MyDbFunct

我想在SQLServer中创建MyDbFunction标量函数,并使用HasDbFunction映射从.NET5应用程序调用它。由于某些原因,映射总是被忽略。我简化了我的示例,以确保它不是签名/参数问题,但这没有帮助。我按照官方文档构建了它:

第一步。 我创建了这个CLR函数:

public int MyCLRFunction (int @Code)
  => throw new NotSupportedException("Mapping issue for MyDbFunction");
第二步。 我将映射添加到我的datacontext SPContext,如下所示:

static void OnModelCreating(ModelBuilder modelBuilder)  
{                 
  modelBuilder.HasDbFunction(typeof(SPContext).GetMethod(nameof(SPContext.MyCLRFunction), new[] 
  { typeof(int) })).HasName("MyDbFunction");
}
当我在调试模式下运行它时,我可以看到调试器在运行OnModelCreating时调用映射。 我希望在调用MyCLRFunction2时,在对数据库调用MyDbFunction之后,它将返回42 using。 它不应该触发CLR函数体中的异常,但总是触发异常。什么会导致映射被忽略

默认架构上SQL函数的代码

Create FUNCTION [dbo].[MyDbFunction]
(
    @Code int
    
)
RETURNS int
AS
BEGIN

return 42

END
我试图添加这个标签,但也没有帮助

[DbFunction("MyDbFunction", "dbo")]
public int MyCLRFunction (int @Code)
  => throw new NotSupportedException("Mapping issue for MyDbFunction");
我尝试将MyCLRFunction定义为另一个类中的静态方法,如官方文档中所建议的:

In the example, the method is defined on DbContext, but it can also be defined as a static method inside other classes.

我不确定这应该如何工作,因为如果它在另一个类中被定义为静态方法,并且在不首先调用datacontext的情况下运行它,则使用HasDbFunction的映射永远不会被调用。

到目前为止,我看到的最有效的方法是:

    public static decimal? MyFunction(int code)
    {
        using (var db = new MyContext())
        {
            try
            {
                return db.AnyEntityWithValues.Take(1).Select(t => db.MyCLRFunction(code).Single();
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }
我希望我可以不使用DataContext的扩展方法

  var myVal = db.MyCLRFunction(code);

只有将查询作为一个整体提供给EF核心提供者进行翻译,映射才有效;如果零件转换为LINQ to对象,则将调用unmapped函数。同样,如果直接调用函数,而不经过DB上下文。也就是说,您可以调用该函数,即使它位于另一个类中,但不能在模型上的LINQ查询之外。这是否意味着如果要独立运行标量函数,必须调用db.MyTable.Singlet=>db.MyCLRFunction2而不是db.MyCLRFunction2?有更合适的方法吗?@sofsntp文档的一节对此进行了解释:此外,由于这些方法的目的是在转换的查询中调用数据库函数,因此尝试在客户端上对它们进行评估会导致异常。。用简单的语言,它们应该仅用作LINQ to Entities查询的一部分。调用从一组参数中检索十进制值的标量函数的最常见方式是什么?在非常不可能的情况下,您真的只想检索标量而不是实体,我想说的是根本不使用EF,只执行一个原始值SqlCommand调用该函数。你可以用简洁的方式使它更令人愉快。或者,您当然可以创建一个只执行SELECT dbo.MyFunction作为X的视图,并将一个实体映射到该视图,这对于单个值来说很笨拙,但如果可以以这种方式返回多个值,则更有意义。一般来说,独立标量T-SQL函数没有什么意义。如果您提供了一个实现,您可以使用Dapper,如果MyCLRFunction属于MyContext,它可以使用this.Database.Connection.executeScalarSelectDBO.MyDbFunction。通过更多的努力,您可能可以从模型中的某个地方获得函数名,而无需硬编码,因此对所有函数使用相同的实现,但我无法一笔勾销。似乎此功能最终会回来,但不会很快回来