开发者

How do I Iterate Linq group result set?

开发者 https://www.devze.com 2023-03-19 07:57 出处:网络
I\'m getting some data from my database and using linq to calculate sums and counts and group the data.

I'm getting some data from my database and using linq to calculate sums and counts and group the data. This is what I have:

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

i now need to pass cs to a method in another class so that I can extract Comm, SIList and Cou开发者_高级运维nt for each item in the group, what type do I pass it as? IEnumerable doesn't work. The actual linq group result type seems to be:

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

Any ideas? I effectively want to pass cs as a variable and iterate through it there.


You'll need to create a type that matches the definition of your anonymous type, if it's going to be used in different scopes.

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

EDIT: I supposed we can assume that the list will be of String so I'm editing for that. If that's the wrong type you'll need to change the IList<T> definition accordingly.


The reason that you get such a complicated type is because the query uses lazy execution. You are looking at the type of the expression that returns the result, not the type of the result.

The type of the result is IEnumerable<_hidden_internal_class_name_>, i.e. as you are creating anonymous objects in the query, the result is a stream of objects of a class that the compiler creates internally.

It's pretty useless to pass on that result to another method, as it would need to use reflection to read the properties in the objects. You should create a named class for the objects in the result, so that it's easy to access its properties.


Creating a type is an excellent idea, but why do that when a returned Tuple can be done without creating a new class or struct? If the need is local and or internal and the class won't be reused, try using a Tuple instead.

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


      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
        */


Pass it as object and in your foreach loop, use var as the iterator.

0

精彩评论

暂无评论...
验证码 换一张
取 消