Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
1 / 1 / 0
Регистрация: 15.08.2017
Сообщений: 21
1
.NET 4.x

Фильтрация данных [LINQ, Reflection]

04.08.2018, 17:03. Показов 2079. Ответов 4

Author24 — интернет-сервис помощи студентам
Имеются данные вида:

ID | Followers | Type | Name
...
79558991 | 3 | PAGE | ВСЕ О ХОККЕЕ
79558989 | 1 | CLOSED COMMUNITY | ДНЕВНИК
...

Пытаюсь с помощью рефлексии и языка запросов сделать универсальную выборку из листа в зависимости от кол-ва операторов where. Передаю в функцию FilterData(selectQuery) словарь, содержащий примерные данные:

<"Followers"<">=", "1">>
<"Name"<"==", "ДНЕВНИК">>

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

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        public void FilterData(Dictionary<string, Dictionary<string, object>> selectQuery)
        {
            FieldInfo[] fi = default(FieldInfo[]);
 
            var queryOperators = selectQuery.Count;
 
            if (queryOperators > 0)
            {
                for (int counter = 0; counter < queryOperators; counter++)
                    fi[counter] = typeof(VKGroup).GetField(selectQuery.Keys.ElementAt(counter));
            }
 
            switch (queryOperators)
            {
                    case 1 :
                    {
                        this.filteredList = (from obj in this.mainList
                                             where Convert.ChangeType(fi[0].GetValue(obj), fi[0].GetType()) > Convert.ChangeType(selectQuery.Values.ElementAt(0).Values.ElementAt(0), fi[0].GetType())
                                             select obj).ToList();
                        break;
                    }
                    ....
            }
        }
Но основная проблема связана с тем, что в операторе where сравниваются 2 объекта типа object, хотя сами свойства класса имеют тип int / string. Как этого избежать или же разрешить?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.08.2018, 17:03
Ответы с готовыми решениями:

LINQ фильтрация списка
Мне нужно отфильтровать (вернуть только то что подходит под условие) массив объектов по одному из...

Фильтрация коллекции в LINQ
Добрый день, форумчане. Вопрос следующего характера. Имеется класс с такими полями: public...

Linq или не Linq. Linq медленней стандартных методов?
Есть у нас два массива, нужно найти совпадения в первом из второго. Два варианта реализации, первый...

Linq фильтрация. "or" неопределенного числа вариантов
Что у меня есть на данный момент oleDbDataAdapter1.Fill(dataSet21.Ігри_Запрос); ...

4
Эксперт JS
6492 / 3903 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
04.08.2018, 20:14 2
true_attack, здесь правильный путь- изучить класс Expression в тонкостях и конструировать выражения.
https://msdn.microsoft.com/ru-... .110).aspx
Этим занимаются единицы программистов.

Помочь можно, но придется тоже много почитать.
0
1 / 1 / 0
Регистрация: 15.08.2017
Сообщений: 21
04.08.2018, 21:31  [ТС] 3
amr-now, я так понял, что нужно копать примерно в эту сторону? https://docs.microsoft.com/ru-... ic-queries
0
Эксперт .NET
6452 / 4053 / 1599
Регистрация: 09.05.2015
Сообщений: 9,487
04.08.2018, 23:45 4
Лучший ответ Сообщение было отмечено true_attack как решение

Решение

Конструктор фильтра
1
1 / 1 / 0
Регистрация: 15.08.2017
Сообщений: 21
05.08.2018, 02:00  [ТС] 5
Идея динамических запросов подтолкнула меня на одну мысль, которую я попытался реализовать (наколхозить) в своем проекте. Может быть кому-нибудь приглянется данное решение. Критика приветствуется.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public void FilterData(Dictionary<string, dynamic[]> query)
{
    query.Add("GroupNumber", new dynamic[] { "GEQ", 5 });
    query.Add("GroupMembers", new dynamic[] { "LEQ", 100 });
 
    PropertyInfo[] fi = new PropertyInfo[query.Count];
 
    if (query.Count > 0)
    {
        for (int counter = 0; counter < query.Count; counter++)
            fi[counter] = typeof(VKGroup).GetProperty(query.Keys.ElementAt(counter), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    }
 
    switch (query.Count)
    {
        case 1:
        {
            this.filteredList = (from obj in this.mainList
                                    where Comparison.Operation(fi[0].GetValue(obj), query.Values.ElementAt(0)[1], Comparison.AutoPickOperation(query.Values.ElementAt(0)[0]))
                                    select obj).ToList();
            break;
        }
        case 2:
        {
            this.filteredList = (from obj in this.mainList
                                    where Comparison.Operation(fi[0].GetValue(obj), query.Values.ElementAt(0)[1], Comparison.AutoPickOperation(query.Values.ElementAt(0)[0]))
                                    where Comparison.Operation(fi[1].GetValue(obj), query.Values.ElementAt(1)[1], Comparison.AutoPickOperation(query.Values.ElementAt(1)[0]))
                                    select obj).ToList();
            break;
        }
        case 3:
        {
            this.filteredList = (from obj in this.mainList
                                    where Comparison.Operation(fi[0].GetValue(obj), query.Values.ElementAt(0)[1], Comparison.AutoPickOperation(query.Values.ElementAt(0)[0]))
                                    where Comparison.Operation(fi[1].GetValue(obj), query.Values.ElementAt(1)[1], Comparison.AutoPickOperation(query.Values.ElementAt(1)[0]))
                                    where Comparison.Operation(fi[2].GetValue(obj), query.Values.ElementAt(2)[1], Comparison.AutoPickOperation(query.Values.ElementAt(2)[0]))
                                    select obj).ToList();
            break;
        }
        case 4:
        {
            this.filteredList = (from obj in this.mainList
                                    where Comparison.Operation(fi[0].GetValue(obj), query.Values.ElementAt(0)[1], Comparison.AutoPickOperation(query.Values.ElementAt(0)[0]))
                                    where Comparison.Operation(fi[1].GetValue(obj), query.Values.ElementAt(1)[1], Comparison.AutoPickOperation(query.Values.ElementAt(1)[0]))
                                    where Comparison.Operation(fi[2].GetValue(obj), query.Values.ElementAt(2)[1], Comparison.AutoPickOperation(query.Values.ElementAt(2)[0]))
                                    where Comparison.Operation(fi[3].GetValue(obj), query.Values.ElementAt(3)[1], Comparison.AutoPickOperation(query.Values.ElementAt(3)[0]))
                                    select obj).ToList();
            break;
        }
        default: break;
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static class Comparison
{
    public static dynamic Operation(dynamic a, dynamic b, Func<dynamic, dynamic, dynamic> comparisonOperator)
    {
        return comparisonOperator(a, b);
    }
 
    public static Func<dynamic, dynamic, dynamic> AutoPickOperation(string stringOperator)
    {
        switch (stringOperator)
        {
            case "EQ": return Operator.EQ;
            case "LEQ": return Operator.LEQ;
            case "GEQ": return Operator.GEQ;
            default: return Operator.EQ;
        }
    }
 
    public static class Operator
    {
        public static dynamic EQ(dynamic a, dynamic b)
        {
            return a == b;
        }
 
        public static dynamic LEQ(dynamic a, dynamic b)
        {
            return a <= b;
        }
 
        public static dynamic GEQ(dynamic a, dynamic b)
        {
            return a >= b;
        }
    }
}
0
05.08.2018, 02:00
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.08.2018, 02:00
Помогаю со студенческими работами здесь

Обновление данных в модели Linq to SQL при обновлении данных в БД
Подскажите новичку. Есть база данных, в приложении настроена работа с БД с помощью Linq to SQL. Из...

Добавление данных в Базу данных Linq to SQL
Добрый день! Делаю регистрацию в приложении, создал таблицу user в БД, и класс сущностей. Таблица...

Фильтрация данных с возможностью изменять данных. framework 2.0
Доброе время суток. У меня возникла такая проблемка))) нужен фильтр для столбца. т.е. пользователь...

Linq Группировка данных
Есть коллекция: id name atherId sum ---------------------- 1, &quot;aaa&quot;, 1, 10 1, ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru