我正在编写一个功能,用户可以输入几个单词来搜索数据库。当我把它移到系统时,代码停止正常工作。
在系统中,查询中只使用搜索词的最后一个单词。
我将相关代码带入LinqPad以查看是否可以复制该问题。它对dev数据库正常工作,并继续对系统数据库失败
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 =' %的疼痛%'
Dev是SQL 2008 R2 Systest是SQL 2005
我计划将数据库移动到Systest中的2008 R2实例,以测试问题是否真的是由数据库版本引起的。
如何在不移动到其他服务器的情况下解决此问题?
答案 0 :(得分: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?