【问题标题】:LINQ to SQL : Unable to use SQL Server UDFs in LINQ queryLINQ to SQL:无法在 LINQ 查询中使用 SQL Server UDF
【发布时间】:2016-06-14 14:09:55
【问题描述】:

我正在做 LINQ to Sql。为了获得良好的性能,我尝试在 SQL Server 端过滤一些记录。所以我想使用我的数据库中可用的用户定义函数(UDF)GiveWordCount。基于this 帖子,这是我在 C# 端尝试使用该 UDF 的方法。

声明一个虚拟函数体,以便 C# 代码可以编译:

[Function(Name = "dbo.GiveWordCount", IsComposable = true)]
public static int GiveWordCount([Parameter(Name="@inputValue",DbType="nvarchar(4000)")]string inputValue)
    {
        throw new NotSupportedException("Direct calls are not supported.");
    }

然后我在我的 LINQ 查询中调用这个函数,如下所示。在最终的 SQL 查询被触发到数据库之前,对“GiveWordCount”函数的调用应该由 LINQ to Sql 提供程序转换为等效的内置 sql 服务器函数。相反,它会导致错误:

方法 'Int32 GiveWordCount(System.String)' 不支持 翻译成 SQL。

这是我的主要功能:

static void Main(string[] args)         
{
    DataContext dataContext = new DataContext("data source=.;initial catalog=businessLinqToSql;integrated security=True;MultipleActiveResultSets=True");

    Table<Customer> customers = dataContext.GetTable<Customer>();
    IEnumerable<string> b = customers.Where(customer => GiveWordCount(customer.Name) <= 2).Select(x => x.Name);


    foreach (string element in b) Console.WriteLine(element);
}

这是我的客户类:

 [Table]
    public class Customer
    {
        [Column]
        public string Name { get; set; }
    }

【问题讨论】:

  • 你的意思是msdn.microsoft.com/en-us/library/…?这不适用于 LINQ to SQL - 它适用于实体框架。
  • 哦。好的@JonSkeet。我的初衷是在 LINQ 查询中使用 UDF(存在于 sql server 中)。因此,当我开始收到此错误时,首先我尝试 IQueryable 是否能够通过 SqlFunctions 类转换内置的 sql 等效函数。看来我得另辟蹊径了。我什至为我的原始问题陈述尝试了这个,但我得到了我提到的非常相同的错误:stackoverflow.com/questions/3865310/…我正在使用 sql-clr 集成来创建我的 UDF。
  • SqlFunctions 的 LINQ to SQL 等价物是 SqlMethods - 但没有那么广泛。我不知道 UDF...
  • 谢谢@JonSkeet。这是很好的信息。 SqlMethods 就像一个魅力。大解脱!你拯救了我的一天。似乎后来控制 LINQ to SQL 的 EF 团队并没有更新这个类,因为他们希望更多地推动实体框架作为 ORM 解决方案。我将深入探讨如何在 C# 代码中的 LINQ 查询中利用 SQL Server UDF。
  • @JonSkeet 我已经针对我面临的原始问题修改了我的问题。我正在使用以下链接来完成它,但它似乎没有工作,并且在 SqlFunctions 类stackoverflow.com/questions/3865310/… 的情况下我得到了同样的错误

标签: c# .net sql-server linq linq-to-sql


【解决方案1】:

我认为该方法需要位于与现有 Linq to Sql DataContext 具有相同命名空间和类名的部分类中。如果你右击你的dbml文件datacontext.dbml => View Code,它会为你生成空的部分类。

例如添加到ISNUMERIC SQL 函数的映射

using System.Data.Linq.Mapping;
namespace SameNamespaceAsDataContext
{
    partial class SameClassnameAsDataContext
    {
        [Function(Name = "ISNUMERIC", IsComposable = true)]
        public int IsNumeric(string input)
        {
            throw new NotImplementedException(); // this won't get called
        }
    }
}

然后按如下方式调用该方法:

IQueryable<int> results = MyDataContext.Table.Select(x => IsNumeric(x.Column));

【讨论】:

    猜你喜欢
    • 2018-09-30
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多