LINQ IQueryable:设置1参数以接受Where子句

时间:2015-07-23 09:33:38

标签: linq entity-framework generics

示例代码

public class program 
{
    public void sample()
    {
        var qry = repo.All(); // returns IQueryable //came from EF
        var keyword = "al";
        var result = qry.DynamicFilter(keyword, filterconditions);
        // it should return all persons with 'al' in their name and nickname
    }

    public List<Expression<Func<Person, string, bool>>> filterconditions
    {
        get
        {
            var ret = new List<Expression<Func<Person, string, bool>>>();
            ret.Add((m,n) => m.Name.Contains(n));
            ret.Add((m,n) => m.Nickname.Contains(n));

            return ret;
        }
    }
}

这是我的扩展

public static class linqExt 
{
    public static IQueryable<T> DynamicFilter<T>(this IQueryable<T> qry, string keyword, IEnumerable<Expression<Func<T, string, bool>>> conditions) where: T
    {
        var ret = qry;
        foreach(var item in conditions)
        {
            ret = ret.Where(m => item.Compile()(m, keyword));
        }

        return ret;
    }
}

有没有办法在不使用Compile / Invoke的情况下实现它?

ret = ret.Where(m =&gt; func.Compile()(m,keyword)); ??

问题是我无法使用Compile,因为该集合是IQueryable,我无法将其转换为IEnumarable,因为如果我这样做,它将从数据库中提取所有数据。

我在想是否可以使用 EXPRESSION 类的 METHODS PROPERTIES

任何客人?感谢

1 个答案:

答案 0 :(得分:0)

我们做了类似的事情;但我们使用此处提供的PredicateBuilder类:https://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

var filter = PredicateBuilder.True<Person>()
                             .And(m => m.Name.Contains(n))
                             .And(m => m.Nickname.Contains(n));

然后你就可以qry.Where(filter),它会应用你的&#34;动态&#34; where子句。如果这是LinqToEF,这将导致Where()子句实际生成并在SQL中执行,这可能是您想要的。

PredicateBuilder是一个非常强大的类,你可以构建一些非常复杂的子句。当你需要做&#34; ORs&#34;时,请确保&#34;开始&#34;使用PredicateBuilder.False<Person>()声明。

你也可以做条件逻辑,&#34;追加&#34;对过滤器的语句,例如:

if (lookingForReallyLongNames == true)
{
    filter = filter.And(m => m.Name.Length > 15);
}
相关问题