MongoDB .Net Linq GroupBy Дочерний массив AsQueryable - PullRequest
0 голосов
/ 20 сентября 2019

Код скрипты

Предположим, у меня есть .Net Class:

public class Bundle
{
    string Name,
    IEnumerable<string> Specs
}

public class ClientProject
{
    string ProjectId,
    decimal PriceSold,
    Bundle  Item
}

И в моем MongoDB я бы имел эти данные:

[
{ProjectId: "1", PriceSold: 100, Item: {Name: "Package1", Specs: ["A", "B"]} } ,
{ProjectId: "2", PriceSold: 500, Item: {Name: "Package10", Specs: ["A", "C"]} } ,
{ProjectId: "3", PriceSold: 900, Item: {Name: "Package100", Specs: ["D", "E"]} } ,
{ProjectId: "4", PriceSold: 50, Item: {Name: "Package90", Specs: ["F"]} } ,
]

Я хочу сгруппировать по Bundle.Specs, чтобы получить такой результат

[
{Spec: "A", Total: 600},
{Spec: "B", Total: 100},
{Spec: "C", Total: 500},
{Spec: "D", Total: 900},
{Spec: "E", Total: 900},
{Spec: "F", Total: 50},
]

Но когда я запускаю этот запрос LINQ, он возвращает неправильную группировку

var result = _coll.AsQueryable()
   .GroupBy(xx=> xx.Item.Specs)
   .Select(xx=> new {GroupId = xx.Key, GroupSum = xx.Sum(yy=> yy.PriceSold)})
   .ToList();

Результат:

[
{GroupId: ["A", "B"], GroupSum: 100},
{GroupId: ["A", "C"], GroupSum: 500},
{GroupId: ["D", "E"], GroupSum: 900},
{GroupId: ["F"], GroupSum: 50},
]

Что не так?

Вот код скрипты:

Код скрипты

1 Ответ

3 голосов
/ 21 сентября 2019

Прежде всего вы должны преобразовать это:

{GroupId: ["A", "B"], GroupSum: 100},
{GroupId: ["A", "C"], GroupSum: 500},
{GroupId: ["D", "E"], GroupSum: 900},
{GroupId: ["F"], GroupSum: 50}

в это:

{Spec: "A", Total: 100},
{Spec: "B", Total: 100},
{Spec: "A", Total: 500},
{Spec: "C", Total: 500},
{Spec: "D", Total: 900},
{Spec: "E", Total: 900},
{Spec: "F", Total: 50}

, поэтому вам следует преобразовать спецификации в IEnumerable<string>, как показано ниже:

var results = collection
    .Select(list => new { Specs = list.Item.Specs.Select(s => string.Join(",", s.Split())), Price = list.PriceSold })
    .SelectMany(i => i.Specs.Select(s => new { Spec = s, i.Price }));

Теперь ваша коллекция готова суммировать дубликаты.Для этого вам нужно добавить GroupBy и Select в ваш запрос:

// this is the final version
var results = collection
    .Select(list => new { Specs = list.Item.Specs.Select(s => string.Join(",", s.Split())), Price = list.PriceSold })
    .SelectMany(i => i.Specs.Select(s => new { Spec = s, i.Price }))
    .GroupBy(g => new { g.Spec, g.Price })
    .Select(i => new { i.Key.Spec, Total = i.Sum(p => p.Price) });

Примечание : Если это не сработало для вас (не волнуйтесь, этоу меня тоже не получилось. Я пробовал с разными версиями .net, но ничего не произошло.), просто удалите GroupBy и last Выберите и добавьте их версию linq в ваш проект.

Ваши запросы должны выглядеть следующим образом:

var results = collection
    .Select(list => new { Specs = list.Item.Specs.Select(s => string.Join(",", s.Split())), Price = list.PriceSold })
    .SelectMany(i => i.Specs.Select(s => new { Spec = s, i.Price }));

var res = from r in rawCollection
          orderby r.Spec
          group r by r.Spec into grp
          let total = grp.Where(x => x.Spec == grp.Key).Sum(x => x.Price)
          select new
          {
              Spec = grp.Key,
              Total = total
          };

И ваш желаемый результат ожидания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...