Linq to sql,在dynamic where子句中使用like

时间:2013-11-13 11:16:01

标签: c# linq dynamic where sql-like

我需要在动态LIKE子句中使用WHERE运算符。

我目前正在使用=运营商,但需要替换为LIKE

String whereClause = "1 = 1 AND ";
whereClause = whereClause + (search.Id != null ? "Id = " + search.Id + " AND " : "");
whereClause = whereClause + (search.FirstName != null ? "FirstName = \"" + search.FirstName + "\" AND " : "");
whereClause = whereClause + (search.LastName != null ? "LastName = \"" + search.LastName + "\" AND " : "");
whereClause = whereClause + (search.StudentName != null ? "StudentName = \"" + search.StudentName + "\" AND " : "");
whereClause = whereClause + (search.Country != null ? "CountryLabel = \"" + search.Country + "\" AND " : "");
whereClause = whereClause + (search.ZipCode != null ? "ZipCode = \"" + search.ZipCode + "\" AND " : "");
whereClause = whereClause + (search.City != null ? "City = \"" + search.City + "\" AND " : "");
whereClause = whereClause.Remove(whereClause.Length - 5);

IEnumerable<MyClassDto> res = (
    from ...
    where ...
    select new MyClassDto() {
        ...
    }
).Where(whereClause);
  1. 我无法使用Contains()StartsWith()EndsWith(),因为搜索参数的格式为“%my%value”。
  2. 我无法在动态SqlMethods.Like()子句中使用WHERE
  3. 我不希望将它包含在WHERE查询的MyClassDto子句中,因为它会减慢执行时间,这就是为什么我在{WHERE上应用另一个Enumerable子句的原因{1}},仅匹配搜索参数。
  4. 有什么建议吗?

2 个答案:

答案 0 :(得分:2)

我会使用PredicateBuilder。

请参见此处:http://www.albahari.com/nutshell/predicatebuilder.aspx

答案 1 :(得分:0)

这可能不如另一个答案中提到的PredicateBuilde那么优雅,但它应该完成工作 你可以提供一个方法作为这样的where子句:
编辑:如果需要,将==替换为任何其他比较运算符。

public bool WhereClause(MyClassDto s, SearchClass search)
{
    if ((s.Id == null || s.Id == search.Id) &&
        (s.FirstName == null || s.FirstName == search.FirstName) &&
        (s.LastName == null || s.LastName == search.LastName) &&
        (s.StudentName == null || s.StudentName == search.StudentName) &&
        (s.Country == null || s.Country == search.Country) &&
        (s.ZipCode == null || s.ZipCode == search.ZipCode) &&
        (s.City == null || s.City == search.City))
    {
        return true;
    }
        return false;
}

用法:

IEnumerable<MyClassDto> res = (
    from ...
    where ...
    select new MyClassDto() {
        ...
    }
).Where(my => WhereClause(my, search));

替代解决方案:

创建方法列表并将它们传递给Where:

var whereClause = new List<Func<MyClassDto, SearchClass, bool>>();
if (search.Id != null) whereClause.Add((s, dto) => s.Id == dto.Id);
if (search.FirstName != null) whereClause.Add((s, dto) => s.FirstName == dto.FirstName);
if (search.LastName != null) whereClause.Add((s, dto) => s.LastName == dto.LastName);
if (search.StudentName != null) whereClause.Add((s, dto) => s.StudentName == dto.StudentName);
if (search.Country != null) whereClause.Add((s, dto) => s.Country == dto.Country);
if (search.ZipCode != null) whereClause.Add((s, dto) => s.ZipCode == dto.ZipCode);
if (search.City != null) whereClause.Add((s, dto) => s.City == dto.City);

IEnumerable<MyClassDto> res = (
    from ...
    where ...
    select new MyClassDto() {
        ...
    }
).Where(dto => whereClause.All(func => func(dto, search)));