Linq to SQL中,动态查询时遇到的问题
今天在WP7项目中检查一个多关键字查询问题,发现一个奇怪的现象,
当使用linq to sql进行多个keyword查询时,我采用循环多个keyword,希望可以实现如注释的代码一样的逻辑,但keyword数量不确定,因此使用foreach 如下:
var query = (from recipe in table where (parameters.CategoryId == "" || recipe.RecipeCatIds.Select(item => item.Cat_Id).Contains(parameters.CategoryId)) //&& recipe.Name.Trim().ToLower().Contains("tee") //&& recipe.Name.Trim().ToLower().Contains("luu") select recipe); foreach (var keyword in keywords) { query = query.Where(recipe => recipe.Name.Trim().ToLower().Contains(keyword)); }
但是返回的结果非常奇怪,使用两个以上的keywords查询,返回的结果都是最后的一个关键字(例如:luu),检查了生成的sql,发现确实是“AND”关系,但@p0始终不起作用,如下:
select xxx from yyy WHERE (LOWER(LTRIM(RTRIM([t0].[Name]))) LIKE @p0) AND (LOWER(LTRIM(RTRIM([t0].[Name]))) LIKE @p1) ORDER BY [t0].[Index], [t1].[Index] }
baidu + google了半天,最后在Jimmy.Yang的文章中找到了答案,增加了一个temp,解决了问题,
foreach (var keyword in keywords) { var temp = keyword; <-- 修改了这里 query = query.Where(recipe => recipe.Name.Trim().ToLower().Contains(temp)); }
以下摘抄自jimmy.yang的文章:
IQueryable查询时,实际上是构建一个Expression Tree(表达式树),如果使用foreach迭代变量时,表达式树实际上得到的只是迭代变量的一个引用,最终运行时将只有最后一次的值,而利用一个临时变量中转一下后,对表达式而言,就是多个变量,会有不同的值
到此,问题解决。