我应该如何初始化的IQueryable变量,使用前联盟体现在哪里?(how should I ini

2019-09-18 04:41发布

我创建了IQueryable的类型,这需要实体的一个子集,并过滤它们在一些criterrions的扩展方法。 我的问题是我无法回报作出的变量的联合表达,不都被首先初始化。 Null值,因为aprears,是无效的。

public static IQueryable<Person> FilterHairColors(this IQueryable<Person> subQuery, string[] hairColors)
    {
        IQueryable<Person> q1 = null;
        IQueryable<Person> q2 = null;
        IQueryable<Person> q3 = null;
        IQueryable<Person> q4 = null;

        foreach (var value in hairColors)
        {
            switch (value)
            {
                case "1":
                    q1 = subQuery.Where(p => p.HairColor_bright == true);
                    break;
                case "2":
                    q2 = subQuery.Where(p => p.HairColor_brown == true);
                    break;
                case "3":
                    q3 = subQuery.Where(p => p.HairColor_dark == true);
                    break;
                case "4":
                    q4 = subQuery.Where(p => p.HairColor_red == true);
                    break;
            }
        }
        return q1.AsQueryable().Union(q2.AsQueryable()).Union(q3.AsQueryable()).Union(q4.AsQueryable());
    }

所呈现的代码块是几个更部分,并且每个产生的数据的一个子集,输送到后续的滤波方法是这样的:

results = persons.FilterGender(vm.gender).FilterAge(vm.age).FilterHeight(vm.height)......  

Answer 1:

不要叫联盟时的一个参数为空。

什么是一个“空查询”对你意味着什么? 如果这意味着“无行”,那么就是不联盟了。 如果这意味着“所有行”您不需要工会的,因为你可以利用基本的,未经过滤的查询。

像这样:

var result = new [] { q1, q2, q3, q4, }.Where(query => query != null).Aggregate(Queryable.Union);

这是使用LINQ到对象构建LINQ到SQL查询。

新版本:

var result = dataContext.Persons.Where(_ => false);
if(q1 != null) result = result.Union(q1);
if(q2 != null) result = result.Union(q2);
if(q3 != null) result = result.Union(q3);
if(q4 != null) result = result.Union(q4);

SQL Server查询优化器将去除第一伪查询,以便它没有运行成本可言。



Answer 2:

public static IQueryable<Person> FilterHairColors(this IQueryable<Person> subQuery, string[] hairColors)
{
    var result = new Person[] { }.AsQueryable();
    var contains = new Dictionary<string, Expression<Func<Person, bool>>>();

    contains.Add("1", p => p.HairColor_bright);
    contains.Add("2", p => p.HairColor_brown);
    contains.Add("3", p => p.HairColor_dark);
    contains.Add("4", p => p.HairColor_red);

    foreach (var color in hairColors)
    {
        result = subQuery.Where(contains[color]).Union(result);
    }

    return result;
}


文章来源: how should I initialize IQueryable variables, before use a Union expression?