“String.Contains方法仅支持可在客户端上评估的参数”

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 filters = query.ToList(); //...more code } 

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

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

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

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

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

看来你应该使用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中是否可行。 您可以创建一个存储过程并将其添加到datacontext,并从输出到一系列ErrorFilter对象进行映射:

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

然后在您的datacontext中,您可以:

 DataContext .GetMatchingFilters(err.ErrorMessage) .Select(result => new ErrorFilter {...}) .ToList(); 

嗯……看起来Linq2SQL IndexOf翻译比Contains更聪明。 这应该工作:

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

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