Можно ли подсчитать количество условий, которые строка удовлетворяет в linq to entity framework

Мне было интересно, есть ли способ подсчитать количество условий, которые удовлетворяет строка, чтобы отсортировать возвращаемое значение по тому, которое соответствует большей части условия.

Допустим, таблица выглядит примерно так:

this

и предположим, что состояние - size=M, или color=blue, или size<40.

В результате я ожидаю примерно такого:

Id3 (3 conditions)
Id4 (2 conditions)
Id1 (1 condition)
Id2 (1 condition)

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

h_w 26.10.2018 09:07

Я не согласен с @TheGeneral - это возможно - так же, как вы можете выполнять условную агрегацию в sql, вы также можете сделать это в linq.

Zohar Peled 26.10.2018 10:44
просыпается ото сна и поднимает брови Я думаю, что постфактум я больше скрывался. Хотя теперь ты так говоришь, я думаю, ты прав
TheGeneral 26.10.2018 10:47

@TheGeneral Да, это можно сделать, хотя держу пари, что кто-то может придумать лучший способ, чем то, что я опубликовал в качестве ответа ....

Zohar Peled 26.10.2018 11:29
1
4
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот один из способов реализовать условную агрегацию с помощью linq.

Обратите внимание, что мне пришлось немного подправить ваше условие, потому что вы написали size=M or color=blue or size<40, но размер - это либо строка, либо число, на самом деле не может быть и тем и другим - поэтому я решил, что это опечатка и должен был быть size=M or color=blue or value<40.

Кроме того, поскольку вы не предоставили MCVE, я сделал это за вас (Пожалуйста попытается создать MCVE для ваших следующих вопросов)

Итак, начнем с простого класса для данных:

class Data
{
    public Data(string id, string size, int value, string color)
    {
        Id = id;
        Size = size;
        Color = color;
        Value = value;
    }

    public string Id {get;set;}

    public string Size {get;set;}

    public int Value {get;set;}

    public string Color {get;set;} 

    public override string ToString()
    {
        return string.Format("Id = {0}, Size = {1}, Value = {2}, Color = {3}", Id, Size, Value, Color);
    }
}

Теперь давайте создадим список этого класса и заполним его образцами данных, которые вы (своего рода) предоставили:

var sampleData = new List<Data>()
{
    new Data("Id1", "L", 35, "red"),
    new Data("Id2", "L", 65, "blue"),
    new Data("Id3", "M", 34, "blue"),
    new Data("Id4", "S", 32, "blue"),
    new Data("Id5", "S", 55, "green")
};

Поскольку я не хотел записывать условия дважды, я решил сначала выбрать новый анонимный тип, содержащий класс Data и другое свойство, которое я назвал ConditionsMatched, для хранения количества условий, которым фактически соответствуют эти данные. Тогда все, что мне нужно было сделать, это отфильтровать результат этого select, чтобы вернуть только те экземпляры, где ConditionsMatched больше, чем 0:

var result = sampleData
    .Select(d => new 
            {
                Data = d,
                ConditionsMatched = 
                    (d.Size == "M" ? 1 : 0) +
                    (d.Color == "blue" ? 1 : 0) +
                    (d.Value < 40 ? 1 : 0)
            })
    .Where(a => a.ConditionsMatched > 0);

В результате получается IEnumerable<AnonymousType>, содержащий только данные, соответствующие хотя бы одному условию.

Вы можете увидеть живую демонстрацию на rextester.

Рад помочь :-)

Zohar Peled 26.10.2018 12:59

Другие вопросы по теме