这个查询将如何转换为动态Linq表达式?

时间:2012-01-23 20:34:31

标签: .net linq search dynamic

select *
    from bis.CompanyInfo ci
    where ci.IsDeleted = 0
        and ci.IsBindingApproved = 1
        and ((ci.[Name] like N'%blah%'
            or ci.CityName like N'%blah%')
            or (ci.[Name] like N'%groupe%'
                or ci.CityName like N'%groupe%'))

认为“blah”和“groupe”是我必须搜索的关键词。要搜索的关键字数量是可变的,这是它需要动态的位置。所以,我可以在0到数百之间找到任意数量的关键字。

任何帮助表示赞赏! =)

2 个答案:

答案 0 :(得分:1)

var result = (from oCompanyInfo as CompanyInfo in CompanyInfoList
             where oCompanyInfo.IsDeleted = 0 and oCompanyInfo.IsBindingApproved = 1 and             
             (Name.Contains("blah") or oCompanyInfo.CityName.Contains("blah") or
             oCompany.Name.Contains("groupe") or oCompany.CityName.Contains("groupe"))
             select oCompanyInfo).ToList()

您可以将“blah”或“group”替换为txt Company Name.Text和text CityName.text(如果过滤器文本位于文本框中)

答案 1 :(得分:0)

似乎有一个订单或类似的东西加入内部过滤器。我们将此代码作为CreateFilter方法的首字母。

private Expression<Func<CompanyInfo, bool>> 
    CreateFilter(SearchCriterion criterion) {
    var outerFilter = PredicateBuilder.True<CompanyInfo>();
    outerFilter = outerFilter.And(ci => !ci.IsDeleted && ci.IsBindingApproved);

    var innerFilter = PredicateBuilder.False<CompanyInfo>();
    foreach(var keyword in criterion.Keywords) {
        var w = keyword;
        innerFilter = innerFilter.Or(ci => ci.Name.Contains(w)
                                        || ci.CityName.Contains(w))
    }
    outerFilter = outerFilter.And(innerFilter);

    if (criterion.HasCityName)
        outerFilter = outerFilter.And(ci => 
            ci.CityName.Contains(criterion.CityName));

    // Other similar filter here...

    return outerFilter;
}

这没有返回正确的结果。然后,根据这篇文章:LINQ: Complicated Advanced Search with Dynamic Where Clause,我更改了我的代码。

private Expression<Func<CompanyInfo, bool>> 
    CreateFilter(SearchCriterion criterion) {
    var innerFilter = PredicateBuilder.False<CompanyInfo>();
    foreach(var keyword in criterion.Keywords) {
        var w = keyword;
        innerFilter = innerFilter.Or(ci => ci.Name.Contains(w)
                                        || ci.CityName.Contains(w))
    }
    var outerFilter = PredicateBuilder.True<CompanyInfo>();
    outerFilter = outerFilter.And(ci => !ci.IsDeleted && ci.IsBindingApproved);

    if (criterion.HasCityName)
        outerFilter = outerFilter.And(ci => 
            ci.CityName.Contains(criterion.CityName));

    // Other similar filter here...

    // Here, we want to include the filter on keywords only when there are 
    // some provided with the search.
    // Otherwise, the result of the And(innerFilter) with no keywords
    // will always be 'false' and return no results though other criterion
    // might be met such as the CityName and whatever the others are.
    if (criterion.HasKeywords) outerFilter = outerFilter.And(innerFilter);

    return outerFilter;
}

它完美无瑕!我真的不明白为什么结果是完美的,因为看起来过滤器的顺序会影响结果,这对我有用。