1

我正在编写一个功能,用户可以输入几个单词来搜索数据库。当我将其移至 systest 时,它的代码停止正常工作。

在 systest 中,查询中仅使用搜索词的最后一个词。

我将相关代码带入 LinqPad,看看是否可以复制该问题。它对 dev 数据库正常工作,并继续对 systest 数据库失败

var cleanTextParts = Regex.Replace("foot pain", @"[^\w]", " ", RegexOptions.None)
    .ToLower()
    .Split(' ')
    .Where(s => !string.IsNullOrEmpty(s));

cleanTextParts.Dump();

var query = ClinicalFindings.AsQueryable();
foreach (var s in cleanTextParts)
    {
        query = query.Where(code => code.Description.ToLower().Contains(s));
    }

var results = query.ToList();
results.Dump();

当我对 Dev 运行它时,这是正在生成并运行的 SQL:

exec sp_executesql N'SELECT [t0].[ClinicalFindingsID], [t0].[ID], [t0].[Description], [t0.[Preferred]
FROM [ClinicalFindings] AS [t0]
WHERE (LOWER([t0].[Description]) LIKE @p0) AND (LOWER([t0].[Description]) LIKE @p1)',N'@p0     varchar(8000),@p1 varchar(8000)',@p0='%pain%',@p1='%foot%'

这是针对 Systest 的:

 exec sp_executesql N'SELECT [t0].[ClinicalFindingsID], [t0].[ID], [t0].[Description], [t0.[Preferred]
 FROM [ClinicalFindings] AS [t0]
 WHERE (LOWER([t0].[Description]) LIKE @p0) AND (LOWER([t0].[Description]) LIKE @p1)',N'@p0     varchar(8000),@p1 varchar(8000)',@p0='%pain%',@p1='%pain%'

注意用于 where 子句的参数的区别:@p0= '%pain%' ,@p1='%pain%' vs @p0= '%foot%' ,@p1='%pain%'

开发是 SQL 2008 R2 系统测试是 SQL 2005

我打算将数据库移动到 Systest 中的 2008 R2 实例,以测试问题是否真的是由数据库版本引起的。

在不移动到其他服务器的情况下如何解决这个问题?

4

1 回答 1

1

对于循环内的 lambda 表达式,这是一个已知的(问题|范围问题|它的工作方式)。我第一次遇到这个时发现了以下 SO 线程,它是一个救星:https ://stackoverflow.com/a/295597/1803682

基本上这是由于重用了 lambda 表达式中的键。链接的答案在解释方面做得很好。快速而肮脏的解决方法是首先复制变量:

foreach (var s in cleanTextParts) {
    var tmp = s;
    query = query.Where(code => code.Description.ToLower().Contains(tmp));
}

我认为您在 LinqPad 中看不到这种行为的原因是,从 C# 5.0 开始,这似乎不再是问题。不是 LinqPad 用户,我猜你在 LinqPad 中使用 C# 5.0,在测试服务器上使用 4.0?

于 2013-09-04T21:29:56.950 回答