"String.Contains方法只支持可在客户端上评估的参数"

6 c# linq asp.net linq-to-sql

public static void MyFunction(MyErrorClass err)
{
    var query = from filter in DataContext.ErrorFilters select filter;
    query = query.Where(f => err.ErrorMessage.Contains(f.ErrorMessage));
    List<ErrorFilter> filters = query.ToList();
    //...more code
}
Run Code Online (Sandbox Code Playgroud)

所以我在上面的代码中遇到了一些问题,而且我从主题行的主题行中得到了错误query.ToList().这是我正在尝试做的事情:

首先,我有一个自定义错误类,MyErrorClass.每当我的网站上发生错误时,我都会MyErrorClass从异常中创建一个对象,将异常中的所有数据存储在该对象中,并将信息存储在数据库中.

我要跟踪的异常属性之一是error(ErrorMessage)的消息.我ErrorFilters在数据库中设置了一个表,用户可以根据该表过滤错误ErrorMessage.所以说你得到了大量的错误,上面写着"System.Data.SqlClient.SqlException:Timeout expired.在操作完成之前已经过了超时时间,或者服务器没有响应.",你想忽略它们.您只需使用ErrorMessage将过滤器添加到数据库为"超时过期",并将其设置为忽略.

现在,上面的类设置为出错,并决定是否应该过滤错误.我正在尝试获取ErrorMessage与错误匹配的所有过滤器的列表.

我确定这是一个简单的解决方案,我只是不知道如何解决它.

Mar*_*urd 8

嗯......看来Linq2SQL的IndexOf翻译比用的更聪明Contains.这应该工作:

public static void MyFunction(MyErrorClass err)
{
    var query = DataContext.ErrorFilters;
    query = query.Where(f => err.ErrorMessage.IndexOf(f.ErrorMessage)>=0);
    List<ErrorFilter> filters = query.ToList();
    //...more code
}
Run Code Online (Sandbox Code Playgroud)

在LinqPad中可以看到这种用途CHARINDEX,因为我们要求的不仅仅是"包含",而是"它在哪里",但它很乐意使用服务器端表达式.

  • 这是纯粹的光彩.人们多年来一直在寻找解决方案!.Select(x =>"text1 | text2 | text3".IndexOf(x.column)> = 0) (2认同)

Lee*_*Lee 0

看来您应该使用f.ErrorMessage.Contains(err.ErrorMessage)-linq to sql 然后将其转换为WHERE ErrorFilter.ErrorMessage LIKE %err.ErrorMessage%. 这种方式的问题在于,生成的 SQL 需要一个动态字符串来匹配 where 子句,因此只能在客户端进行过滤。

顺便说一句,该var query = from filter in DataContext.ErrorFilters select filter;行不是必需的,您可以这样做:

var filters = DataContext.ErrorFilters.Where(f => f.ErrorMessage.Contains(err.ErrorMessage)).ToList();

编辑:

好的,我明白你现在想要做什么,但我不确定这在 linq2sql 中是否可行。您可以创建一个存储过程并将其添加到数据上下文中,然后将输出映射到一系列 ErrorFilter 对象:

create procedure GetMatchingFilters @message varchar(500)
as
begin
    select  *
    from ErrorFilter
    where @message LIKE '%'+ErrorMessage+'%'
end
Run Code Online (Sandbox Code Playgroud)

然后在您的数据上下文中您可以执行以下操作:

DataContext
    .GetMatchingFilters(err.ErrorMessage)
    .Select(result => new ErrorFilter {...})
    .ToList();
Run Code Online (Sandbox Code Playgroud)