Как получить те же результаты из select как foreach при использовании GroupBy () - PullRequest
0 голосов
/ 01 ноября 2018

Я бы хотел получить те же результаты, что и при использовании foreach для группировки при использовании метода select и анонимного метода.

    public class ExportData
    {
        public int Id { get; set; }

        public string Colour { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public int Money { get; set; }
    }

    public class ExportDataDictionary
    {
        public IDictionary<string, object> ColumnData { get; set; } = new Dictionary<string, object>();
    }

Учитывая два класса выше в качестве примера.

Я создаю некоторые данные ..

        var dataCollection = new List<ExportData>
        {
            new ExportData { Name = "Name1", Age = 1, Colour = "Blue", Id = 1, Money = 10 },
            new ExportData { Name = "Name1", Age = 2, Colour = "Red", Id = 2, Money = 20 },
            new ExportData { Name = "Name1", Age = 2, Colour = "Green", Id = 3, Money = 30 },
            new ExportData { Name = "Name2", Age = 1, Colour = "Yellow", Id = 4, Money = 40 },
            new ExportData { Name = "Name3", Age = 2, Colour = "Blue", Id = 5, Money = 50 },
            new ExportData { Name = "Name4", Age = 3, Colour = "Blue", Id = 6, Money = 10 }
        };

Далее я группирую эти данные, например, по двум свойствам следующим образом.

 var dataGrouping = dataCollection.GroupBy(g => new { g.Name, g.Age });

Затем я создаю список ExportDataDictionaries и выполняю поиск по каждой группе в группе, каждый раз создавая новый ExportDataDictionary и добавляя оба ключа в словарь.

        var data = new List<ExportDataDictionary>();

        foreach (var grouping in dataGrouping)
        {
            var datadictionary = new ExportDataDictionary();

            datadictionary.ColumnData.Add("NAME", grouping.Key.Name);
            datadictionary.ColumnData.Add("AGE", grouping.Key.Age);
            data.Add(datadictionary);
        }

Результатом является набор из 5 ExportDataDictionaries с 2 столбцами в каждом, которые содержат пару ключей, соответствующих каждой из групп.

Моя попытка добиться того же с помощью метода Select показана ниже.

        var data2 = new List<ExportDataDictionary>();

        var mydata = dataGrouping.Select(d => 
        {
            var datadictionary = new ExportDataDictionary();
            datadictionary.ColumnData.Add("NAME", d.Key.Name);
            datadictionary.ColumnData.Add("AGE", d.Key.Age);
            data2.Add(datadictionary);
            return data2;
        });

Результат имеет тип:

mydata = {System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<<>f__AnonymousType0<string, int>, ConsoleApp2.Program.ExportData>, System.Collections.Generic.List<ConsoleApp2.Program.ExportDataDictionary>>}

и содержит 5 статей, каждый из которых содержит 10 словарей. Я ожидаю, что 5 словарей имеют те же значения, что и при использовании foreach, но в каждом есть 2 копии. Я полагаю, что это должно быть потому, что он создает словари для обоих ключей, используемых в группировке. Итак, мне интересно, как сделать это только для одного из ключей или только для каждой группы в коллекции?

Требуется, чтобы mydata содержал тот же результат, что и foreach в data переменная

Любая помощь высоко ценится:)

1 Ответ

0 голосов
/ 01 ноября 2018

Просто добавьте .ToList() в конце вашего последнего оператора, удалите оператор data2.Add(datadictionary); и верните только datadictionary return datadictionary;, как это

var mydata = dataGrouping.Select(d =>
        {
            var datadictionary = new ExportDataDictionary();
            datadictionary.ColumnData.Add("NAME", d.Key.Name);
            datadictionary.ColumnData.Add("AGE", d.Key.Age);

            return datadictionary;
        }).ToList();

Я запустил ваш код, проверил и увидел, что mydata содержит 5 элементов, а каждый элемент содержит 2 ColumnData членов.

На самом деле ваш запрос Linq выполняется только при вызове функции .ToList()

...