Tan*_*ira 8 .net c# linq .net-4.0 linq-to-sql
我想使用我在查询中创建的方法,因为我需要实现一种特殊类型的过滤器...
return manager.Clients.SelectAll().Where(cli => cli.Name.SatisfyFilter(filter.Name) && cli.LastName.SatisfyFilter(filter.LastName) && cli.MiddleName.SatisfyFilter(filter.MiddleName)).ToList();
Run Code Online (Sandbox Code Playgroud)
但我明白了:
"方法'布尔SatisfyFilter(System.String,System.String)'没有支持的SQL转换."
错误
我的方法是:
public static bool SatisfyFilter(this string palavra, string filtro)
Run Code Online (Sandbox Code Playgroud)
同样的事情
public bool Contains(string value)
Run Code Online (Sandbox Code Playgroud)
在字符串类型中,Contains工作得很好......
我需要这个方法在IQueryable上运行,因为我的表有2500万个客户端......
我在sql profiler上看到包含在sql中被转换...
我如何实现我的方法将相关的过滤器代码发送到sql?= /
在SQL服务器上创建一个与C#代码等效的用户函数.说它被称为"dbo.SatsFilter".
在datacontext覆盖上创建一个方法,如下所示:
public bool SatisfiesFilter(string name, string filter)
{
// some sort of implementation.
}
Run Code Online (Sandbox Code Playgroud)
使用[Function]和[Parameter]属性装饰C#方法,使其看起来像:
[Function(Name="dbo.SatsFilter",IsComposable=true)]
public bool SatisfiesFilter([Parameter name="@name",DbType="nvarchar(50)"]string name, [Parameter name="@filter",DbType="nvarchar(50)"]string filter)
Run Code Online (Sandbox Code Playgroud)
IsComposable=true 意味着它是一个函数而不是一个存储过程,因此可以用作更大查询的一部分.
您现在可以使用DataContext的此方法,并在适当时将其转换为SQL,或者将在内存中执行的查询中使用C#.
另请注意,如果您只想一直使用SQL(有时很有用),则可以在C#代码中调用方法时调用SQL:
[Function(Name="dbo.SatsFilter",IsComposable=true)]
public bool SatisfiesFilter([Parameter name="@name",DbType="nvarchar(50)"]string name, [Parameter name="@filter",DbType="nvarchar(50)"]string filter)
{
return (bool)ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), name, filter).ReturnValue;
}
Run Code Online (Sandbox Code Playgroud)
当C#等价物方便时,这不是很有用,因为它意味着对数据库的命中和一些翻译,但是如果用户函数依赖于数据库状态或很难很好地转换为C#,那么它很有用.
一个简单的答案是你不能。LINQ to SQL 转换器仅识别部分标准 .NET 方法,您无法添加其他方法。
如果您需要类似的东西,则需要显式创建表达式树(用作 lambda 表达式的主体)。一种直接的方法是使用类的方法Expression,但它可以简化很多。
也许最好的选择是使用LINQKit 项目。它使得调用其他lambda 表达式成为可能(不完全是方法,但接近)。它提供了一个AsExpandable扩展方法,允许您编写:
Expression<Func<Purchase, bool>> customFunction = ...
var data = new MyDataContext();
var query =
from c in data.Purchases.AsExpandable()
where customFunction.Compile()(c)
select c.Name;
Run Code Online (Sandbox Code Playgroud)
这customFunction是一个编译为表达式树的 lambda 函数,您可以在查询中使用它。该AsExpandable扩展将 use 替换为函数体,因此 LINQ to SQL 转换器可以处理此问题。您可以在我的博客文章中详细了解其工作原理。
其他人更详细讨论的其他替代方案是将功能实现为 SQL 用户定义的函数。然后,您可以将该函数拖到数据上下文中并从查询中调用该函数。翻译器将简单地插入对 SQL 函数的调用。