+ Ответить в теме
Показано с 1 по 8 из 8

Тема: C# Динамическое создание запроса

  1. #1
    Супер-модератор MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится Аватар для MetSerp
    Регистрация
    20.10.2008
    Адрес
    Москва
    Сообщений
    3,274

    C# Динамическое создание запроса

    Что то обгуглился я и так и не смог найти вменяемого ответа, как сделать следующее:
    Есть список List с объектами.
    У каждого объекта есть такое свойство Name ( или поле, я не силен в терминологии c# )которое содержит его имя, так же у каждого объекта есть другой список внутри которого тоже есть объекты с полем Name и Value, теперь собственно что я хочу:
    пользователь в консоле вводит строку типа:
    "Имя один"."свойство один">=10; "имя два"."свойство два">-12,10; "Имя три"."Свойство три">-12,10");
    я подхватываю это регуляркой и разбираю на четыре группы:

    _patterns.Add('t',new Regex( "\"(.*?)\"\\.\"(.*?)\"([=|>|<]{1,2})(-?[0-9,]{1,});?",RegexOptions.IgnoreCase ));

    и на основании полученных групп нужно создать linq запрос к списку забрав только удовлетворяющие полученному фильтру результаты
    то есть там где:

    obj.list.name == Имя один || Имя два ||Имя три ->
    obj.list.counters.code == свойство один || свойство два || свойство три
    а значения этих свойств соответсвенно
    obj.list.counters.value >=10||>-12,10||>-12,10



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

  2. #2
    Модератор Alcorn - весьма и весьма положительная личность Alcorn - весьма и весьма положительная личность Аватар для Alcorn
    Регистрация
    13.06.2009
    Адрес
    Россия, Владивосток
    Сообщений
    1,880
    В подобных задачах главное условие понять, что вообще нужно сделать, тогда пойдёт

    Цитата Сообщение от MetSerp Посмотреть сообщение
    Есть список List с объектами.
    У каждого объекта есть такое свойство Name ( или поле, я не силен в терминологии c# )которое содержит его имя, так же у каждого объекта есть другой список внутри которого тоже есть объекты с полем Name и Value
    Я ничё не понял по условию, накидал от балды согласно описанию -



    // на всякий случай, вдруг пригодится
    class ValueComparer : IEqualityComparer<string>
    {
    public bool Equals(string x, string y)
    {
    return x == y;
    }

    public int GetHashCode(string x)
    {
    return x.GetHashCode();
    }
    }

    // объект из внутреннего списка
    public class insideOBJ
    {
    public string Name { get; set; }
    public string Value { get; set; }
    }

    // объект, который в главном списке
    public class mainOBJ
    {
    public string Name { get; set; }
    public List<insideOBJ> Content { get; set; }
    }

    // метод, формирующий всю эту шнягу
    public class Worker
    {
    public List<mainOBJ> result()
    {
    // основной список и список-результат
    List<mainOBJ> list = new List<mainOBJ>(),
    res = new List<mainOBJ>();

    // заполним его чем-нибудь
    list.Add(new mainOBJ {
    Name = "Vasya", Content = new List<insideOBJ>
    {
    new insideOBJ { Name = "address", Value = "Moscow" },
    new insideOBJ { Name = "phone", Value ="8914000000" }
    }
    });

    list.Add(new mainOBJ {
    Name = "Petya", Content = new List<insideOBJ>
    {
    new insideOBJ { Name = "address", Value = "Tula" },
    new insideOBJ { Name = "postcode", Value = "123456" }
    }
    });

    // "Имя один"."свойство один">=10; "имя два"."свойство два">-12,10; "Имя три"."Свойство три">-12,10");
    // это прислал пользователь, разобрали и получили 4 массива
    string[] nameInput = { "Masha", "Petya", "Vladislav" };
    string[] nameInputInside = { "postcode", "Firstnane", "Bill" };
    string[] nameInputValue = { "Tula", "Vladivostok", "Rostov" };
    //string[] conditions = { ">", "<", "=" };
    /*
    // / или 3 объекта
    mainOBJ obj1 = new mainOBJ
    {
    Name = nameInput[0],
    Content = new List<insideOBJ>
    {
    new insideOBJ { Name = nameInputInside[0], Value = nameInputValue[0] }
    }
    };
    */
    res = list.Where<mainOBJ>(x => nameInput.Contains<string>(x.Name) && nameInputInside.Intersect(((List<insideOBJ>)x.Content).Select(xx => xx.Name)).Count() != 0 && nameInputValue.Intersect(((List<insideOBJ>)x.Content).Select(xxx => xxx.Value), new ValueComparer()).Count() != 0).ToList<mainOBJ>();

    // из первоначального списка сюда попадают только те объекты, у которых во всех 3-ёх свойствах совпадает хотя бы одно из значений, которое ввёл пользователь (Name, Name, Value)
    // а вообще условие не понял - больше меньше, равно, это куда, в реальные условия сравнения? Тогда на всякий случай comparer вынес для интерсекта.
    return res;
    }
    }

    // вызов -
    Worker worker = new Worker();
    List<mainOBJ> res = worker.result();
    ASP.NET, Oracle

  3. #3
    Супер-модератор MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится Аватар для MetSerp
    Регистрация
    20.10.2008
    Адрес
    Москва
    Сообщений
    3,274
    видимо я запутал с тем примером что надо получить :)

    в общем объект выглядит так:

    string Name ;
    List<Accounts> Accounts;
    ----List<Counters> Counters;
    ----------------------string Name;
    ---------------------decimal Value;
    Таких объектов у меня целый список:
    List<CardAccessor> cards;
    мне надо из этого списка сформировать список таких объектов, которые удовлетворяют произвольному фильтру вида :
    "Имя один"."свойство один">=10; "имя два"."свойство два">-12,10;
    Распарсить запрос на составляющие проблемы нет, проблема именно сформировать LINQ и чтобы компилятор потом понял что это не просто строка а linq запрос
    то что набыдлокодил я -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using Resto.Card.Presentation.DTO;

    namespace ConsoleApplication.Core
    {
    class Filter
    {
    private readonly string _rawFilter;
    private string _filter;
    private readonly Dictionary<char ,Regex> _patterns= new Dictionary<char, Regex>();
    public Filter (string rawFilter)
    {
    _patterns.Add('t',new Regex( "\"(.*?)\"\\.\"(.*?)\"([=|>|<]{1,2})(-?[0-9,]{1,});?",RegexOptions.IgnoreCase ));
    _patterns.Add('p', new Regex("\"(.*?)\"([=|>|<]{1,2})(-?[0-9,]{1,});?", RegexOptions.IgnoreCase));
    _rawFilter = rawFilter;
    _filter = Parse();

    }
    private string Parse()
    {

    var result = "from card in cards where";
    var types = _rawFilter.Split('|');
    foreach (string type in types)
    {
    Regex pattern;
    _patterns.TryGetValue(type.First(), out pattern);
    if (pattern != null)
    {
    var matches = pattern.Matches(type);
    if (type.First() == 't')
    {
    foreach (Match matche in matches)
    {
    result += "((card.Accounts.Name==\""+matche.Groups[1]+"\").Counters.Name==\""+matche.Groups[2]+"\").Value"+matche.Groups[3]+matche.Groups[4];// вот тут я пытался формировать запрос но получается чушь.
    }
    }
    else if (type.First() == 'p')
    {
    foreach (Match matche in matches)
    {

    }
    }

    }
    }
    return result;
    }
    public override string ToString()
    {
    return _filter;
    }
    public List<CardAccessor> AplyFilter(List<CardAccessor> cards )
    {
    return new List<CardAccessor>();
    }
    }
    }

    конкретно проблема у меня с методом Parse - он кривой, я не могу сформировать linq
    и с методом AplyFilter, ибо раз у меня нет готового запроса я не могу по нему фильтровать Список

  4. #4
    Модератор Alcorn - весьма и весьма положительная личность Alcorn - весьма и весьма положительная личность Аватар для Alcorn
    Регистрация
    13.06.2009
    Адрес
    Россия, Владивосток
    Сообщений
    1,880
    Сама идея парсить строки, соединять распарсенное в строку кода языка и затем его eval-ить - весьма странная. Почему нельзя список отфильтровать по Where? Это тот же самый linq. Результирующий_список = существующий_список.Where<тип _объекта_в_списке>(x => x.Name_имя_существующего_объе? ?та == Name_имя_объекта_введённое_по льзователем && остальные_условия_фильтра). Если сильно хочется, то можно linq из строки выполнить, есть либы готовые, делающие всю работу, но это как-то через зад :)
    ASP.NET, Oracle

  5. #5
    Супер-модератор MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится MetSerp за этого человека можно гордится Аватар для MetSerp
    Регистрация
    20.10.2008
    Адрес
    Москва
    Сообщений
    3,274
    Об евале как раз речь не идет, единственное что я пока придумал это делать в цикле пока не кончаться фильтры то есть в псевдокоде это как то так:

    var resultList = startList
    foreach (conditions){
    resultList = resultList.Where(условие);
    }
    return resultList;

    главная проблема можно ли передать в Where условие строкой? ибо иначе я не понимаю как реализовать разные варианты сравнения (==|<=|>=|!=)

  6. #6
    Модератор Alcorn - весьма и весьма положительная личность Alcorn - весьма и весьма положительная личность Аватар для Alcorn
    Регистрация
    13.06.2009
    Адрес
    Россия, Владивосток
    Сообщений
    1,880
    Цитата Сообщение от MetSerp Посмотреть сообщение
    главная проблема можно ли передать в Where условие строкой? ибо иначе я не понимаю как реализовать разные варианты сравнения (==|<=|>=|!=)
    Если исполнять конструкцию языка из строки, то это как раз "eval", в C# код можно откомпилить и выполнить, есть CodeDOM и Expression (здесь как раз показано на примере Where).

    Можно условий напихать, по типу этого -


    string name = "Masha";
    int value = 30;
    string cond = ">";

    list.Add(new mainOBJ { Name = "Vasya", Content = 10 });
    list.Add(new mainOBJ { Name = "Masha", Content = 20 });
    list.Add(new mainOBJ { Name = "Petya", Content = 30 });

    res = list.Where<mainOBJ>(x => x.Name == name && (cond == ">" ? x.Content > value : (cond == "<" ? x.Content < value : x.Content == value))).ToList();


    p.s. вчера переезжал с vds win2008 на облако win2012, интерфейс у новой серверной винды жесть, пока понял куда тыкать надо, пол дня прошло :) И форум моё предыдущее сообщение сожрал наполовину, может обновления уже для форума есть какие-нибудь.
    ASP.NET, Oracle

  7. #7
    bj.list.counters.code == свойство один || свойство два || свойство три
    а значения этих свойств соответсвенно
    obj.list.counters.value >=10||>-12,10||>-12,10

    _______________
    Prep4sure.mobi Cisco 300-320 Cisco 300-085 VCE JK0-802 Testking 1z0-133 PDF HP2-Z34 Answers NS0-155
    Последний раз редактировалось johson; 29.01.2016 в 13:41.

  8. #8
    Sonu-Exchange is charmed to advance particular online coin exchange advantages despite dispatching a not too bad and centered rates of exchange. http://goo.gl/ILJMp9

+ Ответить в теме

Похожие темы

  1. Динамическое создание ссылок
    от Bartle96 в разделе PHP
    Ответов: 1
    Последнее сообщение: 07.02.2012, 15:10
  2. Ответов: 16
    Последнее сообщение: 26.06.2011, 18:15
  3. Ответов: 5
    Последнее сообщение: 01.05.2011, 15:28
  4. Динамическое меню из БД
    от Azizbek в разделе Базы данных
    Ответов: 6
    Последнее сообщение: 10.08.2010, 09:13
  5. Ответов: 6
    Последнее сообщение: 06.08.2010, 00:07

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения