Группировка по переменному значению потолка с максимумом catch-all с использованием LINQ для NHibernate


Я хотел бы построить оператор LINQ GroupBy в соответствии со следующими десятичными категориями: 0-50, 50-100, 100-250, 250-выше. Я нашелGroup by variable integer range, используя Linq , в котором обсуждается, как использовать переменный диапазон, но этот запрос имеет конечную верхнюю границу. Мой запрос должен быть в состоянии обрабатывать все, что превышает 250, как одна группа. Я попробовал использовать десятичную дробь.maxValue как моя верхняя граница, но запрос не смог ее обработать, я полагаю, потому что значение больше, чем то, что NHibernate может обрабатывать. В идеале я хотел бы сделать это без указания максимального значения, чтобы запрос не зависел от базы данных.

Edit: я почти уверен, что могу сделать это, используя массив значений этажей и следуя шаблону в ссылке. Но мне любопытно, есть ли какая-то общая групповая конструкция.

1 2

1 ответ:

Редактировать:

Вы изменили OP, чтобы указать, что вы можете использовать функцию floor, но вы хотели узнать о группировке по умолчанию.

Математически функция пола эквивалентна. В случае потолка нижняя граница для данных, которые они использовали, предположительно равна 0. В случае floor логической верхней границей является положительная бесконечность (фактически это самое высокое значение, которое поддерживает БД, поскольку целые числа не поддерживают концепцию бесконечности). Он тебя достает куда ты хочешь пойти.

Если вы хотите что-то, что может быть более применимо к другим ситуациям, вы можете попробовать что-то вроде этого:

items.GroupBy(item =>
    (
        floors.FirstOrDefault(floor => floor <= item)
            ?? "Default"
        )
        .ToString()
    );

Это, вероятно, не будет работать в Linq для NHibernate, так как я не думаю, что это будет хорошо сопоставляться с SQL. Вместо этого вы можете сначала импортировать весь набор в память (.ToList()), а затем добавить свою группировку в качестве запроса Linq к объектам.

Не имеет большого смысла использовать его в этой ситуации, но это может быть в случае не-числовой строки группировки:

var groups = new HashSet<string>
{
    "Orange",
    "Green",
    "Mauve",
};

items.GroupBy(item =>
    groups.Contains(item.Color)
        ? item.Color
        : "Default"
    );

Перед Редактированием:

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

var floors = new[] { 250, 100, 50, 0 };
var groupings = items.GroupBy(item => floors.First(floor => floor <= item));

Как это работает:

  • Возьмите предмет 270.
    Первым пунктом в списке будет первое ведро, под которое он попадает. Это потому, что 250 <= 270.

  • Возьмите предмет 99.
    Третьим пунктом в списке будет первое ведро, под которое он попадает. 250 не меньше, чем 99. 100 не меньше, чем 99. Но 50 меньше, чем 99.

  • Предмет 50 упал бы в третье ведро.
    Она меньше 250 и 100, но равна 50.

Не совсем соответствует описанию в вашем вопросе:

Ваше описание группы немного нарушено. Для того чтобы этот алгоритм работал, их нужно было бы монетизировать отдельно. Было бы ведро 0-50, ведро 51-100 и т. д. Или 0-49 ведро, A 50-99 ведро и т. д.

Ведро 0-50 и ведро 50-100 не могут существовать вместе.