How would this query translate into a dynamic Linq expression?

房东的猫 提交于 2019-12-13 04:42:29

问题


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%'))

Consider that "blah" and "groupe" are keywords that I must search for. The number of keywords to search for is variable, that is where it needs to be dynamic. So, I could have any number of keywords to look for from 0 to hundreds.

Any help is appreciated! =)


回答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()

There you can replace "blah" or "groupe" to txtCompanyName.Text and txtCityName.text (if the filter text is in a textbox)




回答2:


It seems like there is an order or the-like to join the inner filter. Let's take this code as the initial from my CreateFilter method.

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;
}

This was not returning the right results. Then, per this article: LINQ: Complicated Advanced Search with Dynamic Where Clause, I changed my code.

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;
}

And it works flawlessly! I don't really understand why the results are perfect only as it appears the order of the filters impacts the results, and this worked for me.



来源:https://stackoverflow.com/questions/8978174/how-would-this-query-translate-into-a-dynamic-linq-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!