Как мне повторить набор результатов группы Linq? - PullRequest
5 голосов
/ 08 июля 2011

Я получаю некоторые данные из своей базы данных и использую 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 ]

7 голосов
/ 08 июля 2011

Вам нужно будет создать тип, который соответствует определению вашего анонимного типа, если он будет использоваться в разных областях.

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>.

3 голосов
/ 08 июля 2011

Причина, по которой вы получаете такой сложный тип, заключается в том, что запрос использует отложенное выполнение.Вы смотрите на тип выражения, которое возвращает результат, а не на тип результата.

Тип результата - IEnumerable<_hidden_internal_class_name_>, т. Е. Когда вы создаете анонимные объекты в запросе, результатэто поток объектов класса, который компилятор создает внутри.

Передавать этот результат другому методу довольно бесполезно, так как для чтения свойств объектов необходимо использовать отражение.Вы должны создать именованный класс для объектов в результате, чтобы было легко получить доступ к его свойствам.

0 голосов
/ 04 января 2016
      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
        */
0 голосов
/ 08 июля 2011

Создание типа - отличная идея, но зачем это делать, когда возвращаемый Tuple может быть выполнен без создания нового класса или структуры?Если необходимость локальная и / или внутренняя, и класс не будет использоваться повторно, попробуйте вместо этого использовать Tuple.

Select new Tuple<Comm, IEnumerable<string>, Int32>( new Comm(), myStringList.AsEnumerable(), myCount )
0 голосов
/ 08 июля 2011

Передайте его как object и в цикле foreach используйте var в качестве итератора.

...