【问题标题】:lambda query to lower in C#在 C# 中降低 lambda 查询
【发布时间】:2012-08-08 14:42:09
【问题描述】:

我在 lambda 查询中遇到了 toLower() 的问题。我有这个代码

var filterResult = articleList
                        .Where(m => m.Summary
                            .Contains(filteredModel.Keyword) || m.Body.Contains(filteredModel.Keyword) || m.Headline.Contains(filteredModel.Keyword) 
                            || m.Title.Contains(filteredModel.Keyword))
                        .AsQueryable();

我需要将 toLower() 方法添加为 sql。例如:

var filterResult = articleList
    .Where(m => m.Summary.toLower()
        .Contains(filteredModel.Keyword.toLower()) || m.Body.toLower().Contains(filteredModel.Keyword.toLower()) || m.Headline.toLower().Contains(filteredModel.Keyword.toLower()) 
        || m.Title.toLower().Contains(filteredModel.Keyword.toLower()))
    .AsQueryable();

如上代码,lambda 不允许使用。我想知道是否有其他方法可以做到这一点。

【问题讨论】:

  • 你得到什么错误信息?
  • .toLower() 应该是 .ToLower()
  • 在 C# 中,方法是 ToLower() 而不是 toLower(),不确定这是否是拼写错误,但 ToLower() 应该完全合法使用。
  • @MarkByers 他会得到一个不受支持的异常,因为 SQL 中没有 ToLower 方法。他需要的是 SQL 中不区分大小写的包含。
  • 可能是 EF / Linq2SQL 等无法将函数映射到数据库中。如果您的表上有不区分大小写的排序规则,则不需要 ToLower?

标签: c# asp.net-mvc lambda


【解决方案1】:

ToLower 应该可以工作,尝试将其分成不同的行以缩小检查失败的范围 - 请记住,直到您实际将结果拉下来,它才会执行,例如

var keyword = filteredModel.Keyword.ToLower();
var filterResult = articleList.Where(m => m.Summary.ToLowerInvariant().Contains(keyword));
filterResult = filterResult.Where(m => m.Body.ToLower().Contains(keyword));
filterResult = filterResult.Where(m => m.Headline.ToLower().Contains(keyword));
filterResult = filterResult.Where(m => m.Title.ToLower().Contains(keyword));

也只是一个仅供参考 - 如果您转换为小写以进行与文化无关的比较,那么您应该使用ToLowerInvariant...或者更好的是使用ToUpperInvariant,因为它更多的是reliable

【讨论】:

  • 问题仍然存在,LINQ 提供程序不支持这些方法。
【解决方案2】:

你可以用

达到同样的效果
    .Where(m => m.Summary.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Body.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Headline.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Title.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 

我认为应该得到您的 Linq 提供商的支持

您可以通过创建扩展方法使as described here 更整洁

public static bool Contains(this string source, string toCheck, StringComparison comp) {
  return source.IndexOf(toCheck, comp) >= 0;
}

所以你可以这样做

.Where(m => m.Summary.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Body.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Headline.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Title.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2014-12-25
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    相关资源
    最近更新 更多