如何迭代Linq组结果集?

时间:2011-07-08 12:54:04

标签: c# linq iterator ienumerable

我从我的数据库中获取一些数据并使用linq计算总和和计数并对数据进行分组。 这就是我所拥有的:

        var si = _repository.GetAllByDate(date);

        var cs = from s in si
        group s by s.Name into g
        select new { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

我现在需要将cs传递给另一个类中的方法,以便我可以为组中的每个项目提取Comm,SIList和Count,我将它传递给哪个类型? IEnumerable不起作用。实际的linq组结果类型似乎是:

{System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<Model.Domain.MasterData .MyItem,Model.Domain.SI<>f__AnonymousTyped<Model.Domain.MasterData.MyItem,System.Collections.Generic.List<Model.Domain.SI>,int>>}

有什么想法吗?我实际上想要将cs作为变量传递并在那里迭代。

5 个答案:

答案 0 :(得分:7)

如果它将在不同的范围内使用,您需要创建一个与匿名类型定义相匹配的类型。

public class SomeClass {
    public Comm Comm { get; set; }
    public IList<String> SIList { get; set; }
    public Int32 Count { get; set; }
}

var si = _repository.GetAllByDate(date);

var cs = from s in si
         group s by s.Name into g
         select new SomeClass { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

编辑:我想我们可以假设列表是String,所以我正在编辑。如果这是错误的类型,您需要相应地更改IList<T>定义。

答案 1 :(得分:3)

您获得如此复杂类型的原因是因为查询使用了延迟执行。您正在查看返回结果的表达式的类型,而不是结果的类型。

结果的类型是IEnumerable<_hidden_internal_class_name_>,即在查询中创建匿名对象时,结果是编译器在内部创建的类的对象流。

将结果传递给另一个方法是没有用的,因为它需要使用反射来读取对象中的属性。您应该为结果中的对象创建一个命名类,以便可以轻松访问其属性。

答案 2 :(得分:0)

创建一个类型是一个很好的想法,但是为什么在没有创建新类或结构的情况下可以完成返回的Tuple?如果需要是本地的或内部的,并且该类不会被重用,请尝试使用元组。

Select new Tuple<Comm, IEnumerable<string>, Int32>( new Comm(), myStringList.AsEnumerable(), myCount )

答案 3 :(得分:0)

      class Pet
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        // Uses method-based query syntax.
        public static void GroupByEx1()
        {
            // Create a list of pets.
            List<Pet> pets =
                new List<Pet>{ new Pet { Name="Barley", Age=8 },
                               new Pet { Name="Boots", Age=4 },
                               new Pet { Name="Whiskers", Age=1 },
                               new Pet { Name="Daisy", Age=4 } };

            // Group the pets using Age as the key value 
            // and selecting only the pet's Name for each value.
            IEnumerable<IGrouping<int, string>> query =
                pets.GroupBy(pet => pet.Age, pet => pet.Name);

            // Iterate over each IGrouping in the collection.
            foreach (IGrouping<int, string> petGroup in query)
            {
                // Print the key value of the IGrouping.
                Console.WriteLine(petGroup.Key);
                // Iterate over each value in the 
                // IGrouping and print the value.
                foreach (string name in petGroup)
                    Console.WriteLine("  {0}", name);
            }
        }

        /*
         This code produces the following output:

         8
           Barley
         4
           Boots
           Daisy
         1
           Whiskers
        */

答案 4 :(得分:-2)

将其作为object传递,并在foreach循环中,使用var作为迭代器。