减少LINQ查询的数量

时间:2011-03-23 22:46:37

标签: linq query-optimization

void Main()
    {
        List<SomeContainer> someList = new List<SomeContainer>();
        someList.Add(new SomeContainer { a = true, b = true, c = true });
        someList.Add(new SomeContainer { a = false, b = true, c = false });
        someList.Add(new SomeContainer { a = true, b = true, c = false });
        someList.Add(new SomeContainer { a = true, b = false, c = false });
        someList.Add(new SomeContainer { a = true, b = false, c = false });
        someList.Add(new SomeContainer { a = true, b = true, c = false });
        someList.Add(new SomeContainer { a = true, b = true, c = false });

        var q1 = from container in someList where container.a == true select container.a;
        var q2 = from container in someList where container.b == true select container.b;
        var q3 = from container in someList where container.c == true select container.c;
        q1.Count().Dump();
        q2.Count().Dump();
        q3.Count().Dump();
    }

    class SomeContainer
    {
        public Boolean a { get; set; }
        public Boolean b { get; set; }
        public Boolean c { get; set; }
    }

是否可以用一个querry生成这样的东西:
a | b | c
6 | 5 | 1

4 个答案:

答案 0 :(得分:4)

不确定您是否将其视为优化,但这只会在您的列表中迭代一次:

var result = someList
        .Select(i => new [] {i.a? 1:0, i.b? 1:0, i.c? 1:0,})
        .Aggregate((i, acc) => new [] {i[0]+acc[0], i[1]+acc[1], i[2]+acc[2]});

int countA = result[0];
int countB = result[1];
int countC = result[2];

答案 1 :(得分:1)

int a = 0, b = 0, c = 0;
var qAll = (from ct in someList
            select new{ ac  = ct.a ? a++ : 0,  
                        bc =  ct.b ? b++ : 0,
                        cc = ct.c ? c++ : 0}).ToList();

//Now a, b, c variables should have the count of a==true, b==true & c==true in somelist.
//Console.WriteLine("A= {0}, B={1}, C={2}", a, b, c);

答案 2 :(得分:0)

Aggregate扩展方法允许您以任意方式组合来自枚举的值。您可以聚合表示计数的三个整数的元组,并提供一个函数,该函数将根据输入递增元组上的三个计数器。

它怀疑这个例子可能看起来很狡猾,而且它可能比常规for循环慢。

有时Aggregate会闪耀。我用它来计算矩形列表的边界矩形:var union = rects.Aggregate(Rectangle.Union);

答案 3 :(得分:0)

someList.Count(container => container.a).Dump();
someList.Count(container => container.b).Dump();
someList.Count(container => container.c).Dump();
//even when looking for false values it looks nice...
someList.Where(container => container.a == false).Count(container => container.a).Dump();