Как выбрать группу по значениям в указанном c propoerty? - PullRequest
0 голосов
/ 16 марта 2020

Я использую группу путем выбора, используя ядро ​​структуры сущностей и linq.

var list = context.Ways.GroupBY(s=>s.Type).Select(w=> new {
    type = w.key,
    total = (int)w.Sum(b => b.Length)
})

Это дает мне список.

type        total
T1          2541
T2          5481
T5          4
T9          2
T11         856
T3          25

Поэтому я хочу сгруппировать в "Другие" , если итоговое значение меньше 100, как указано ниже,

type        total
T1          2541
T2          5481
T11         856
OTHERS      31

возможно ли это?

Ответы [ 3 ]

0 голосов
/ 16 марта 2020

Вы можете сделать это со второй группой, набрав

var list = context.Ways.GroupBy(s => s.Type).Select(w => new
{
    type = w.Key,
    total = (int)w.Sum(b => b.Length)
}).GroupBy(s => s.total < 100 ? "Others" : s.type)
.Select(w => new
{
    type = w.Key,
    total = (int)w.Sum(b => b.total)
});
0 голосов
/ 16 марта 2020

Технически вы можете добавить дополнительную операцию, которая вычислила бы значение Others на основе двух уже собранных значений. Как это:

var list = context.Ways.GroupBy(s=>s.Type).Select(w=> new {
    type = w.key,
    total = (int)w.Sum(b => b.Length)
});

var totalSum = context.Ways.Sum(x => x.Length);
var listSum = list.Sum(x => x.total);

list.Add(new {
    type = "Others",
    total = totalSum - listSum
});
0 голосов
/ 16 марта 2020

Вы не можете сделать это с Entity Framework, но вы можете написать метод для перебора списка в памяти. Например, если у вас есть класс для хранения ключа и значения, как это (или вы можете переписать, используя KeyValuePair или кортеж):

public class ItemCount
{
    public string Name { get; set; }
    public int Count { get; set; }
}

Метод расширения для агрегирования меньших значений может выглядеть следующим образом это:

public static IEnumerable<ItemCount> AggregateWithThreshold(this IEnumerable<ItemCount> source, 
    int threshold)
{
    // The total item to return
    var total = new ItemCount
    {
        Name = "Others",
        Count = 0
    };

    foreach (var item in source)
    {
        if (item.Count >= threshold)
        {
            // If count is above threshold, just return the value
            yield return item;
        }
        else
        {
            // Keep the total count
            total.Count += item.Count;
        }
    }

    // No need to return a zero count if all values were above the threshold
    if(total.Count > 0)
    {
        yield return total;
    }

}

И вы бы назвали это так:

var list = context.Ways
    .GroupBY(s => s.Type)
    .Select(w => new ItemCount // Note we are using the new class here
    {
        Name = w.key,
        Count = (int)w.Sum(b => b.Length)
    });

var result = list.AggregateWithThreshold(100);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...