X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

Открыть тему
Тема закрыта
> C# Динамическое создание запроса
MetSerp
MetSerp
Topic Starter сообщение 24.7.2013, 12:02; Ответить: MetSerp
Сообщение #1


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

я подхватываю это регуляркой и разбираю на четыре группы:

[JS]_patterns.Add('t',new Regex( "\"(.*?)\"\\.\"(.*?)\"([=|>|<]{1,2})(-?[0-9,]{1,});?",RegexOptions.IgnoreCase ));[/JS]
и на основании полученных групп нужно создать linq запрос к списку забрав только удовлетворяющие полученному фильтру результаты
то есть там где:

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



как сгенерировать и выполнить запрос над списком и как он будет выглядить в данном случае?
В sql я бы просто сгенерировал строку и отдал бы ее запросом, а тут у меня возникают вопросы
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Alcorn
Alcorn
сообщение 24.7.2013, 15:50; Ответить: Alcorn
Сообщение #2


В подобных задачах главное условие понять, что вообще нужно сделать, тогда пойдёт :)

(MetSerp @ 24.7.2013, 15:02) *
Есть список List с объектами.
У каждого объекта есть такое свойство Name ( или поле, я не силен в терминологии c# )которое содержит его имя, так же у каждого объекта есть другой список внутри которого тоже есть объекты с полем Name и Value


Я ничё не понял по условию, накидал от балды согласно описанию -

[PHP]

// на всякий случай, вдруг пригодится
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();
[/PHP]
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
MetSerp
MetSerp
Topic Starter сообщение 24.7.2013, 17:00; Ответить: MetSerp
Сообщение #3


видимо я запутал с тем примером что надо получить :)

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

string Name ;
List<Accounts> Accounts;
----List<Counters> Counters;
----------------------string Name;
---------------------decimal Value;


Таких объектов у меня целый список:
List<CardAccessor> cards;


мне надо из этого списка сформировать список таких объектов, которые удовлетворяют произвольному фильтру вида :
"Имя один"."свойство один">=10; "имя два"."свойство два">-12,10;

Распарсить запрос на составляющие проблемы нет, проблема именно сформировать LINQ и чтобы компилятор потом понял что это не просто строка а linq запрос
то что набыдлокодил я -

[php]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>();
}
}
}
[/php]
конкретно проблема у меня с методом Parse - он кривой, я не могу сформировать linq
и с методом AplyFilter, ибо раз у меня нет готового запроса я не могу по нему фильтровать Список
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Alcorn
Alcorn
сообщение 25.7.2013, 14:49; Ответить: Alcorn
Сообщение #4


Сама идея парсить строки, соединять распарсенное в строку кода языка и затем его eval-ить - весьма странная. Почему нельзя список отфильтровать по Where? Это тот же самый linq. Результирующий_список = существующий_список.Where<тип_объекта_в_списке>(x => x.Name_имя_существующего_объекта == Name_имя_объекта_введённое_пользователем && остальные_условия_фильтра). Если сильно хочется, то можно linq из строки выполнить, есть либы готовые, делающие всю работу, но это как-то через зад :)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
MetSerp
MetSerp
Topic Starter сообщение 25.7.2013, 15:54; Ответить: MetSerp
Сообщение #5


Об евале как раз речь не идет, единственное что я пока придумал это делать в цикле пока не кончаться фильтры то есть в псевдокоде это как то так:

[PHP]var resultList = startList
foreach (conditions){
resultList = resultList.Where(условие);
}
return resultList;[/PHP]
главная проблема можно ли передать в Where условие строкой? ибо иначе я не понимаю как реализовать разные варианты сравнения (==|<=|>=|!=)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Alcorn
Alcorn
сообщение 27.7.2013, 8:37; Ответить: Alcorn
Сообщение #6


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


Если исполнять конструкцию языка из строки, то это как раз "eval", в C# код можно откомпилить и выполнить, есть CodeDOM и Expression (здесь как раз показано на примере Where).

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

[PHP]
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();
[/PHP]

p.s. вчера переезжал с vds win2008 на облако win2012, интерфейс у новой серверной винды жесть, пока понял куда тыкать надо, пол дня прошло :) И форум моё предыдущее сообщение сожрал наполовину, может обновления уже для форума есть какие-нибудь.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
johson
johson
сообщение 22.1.2015, 9:42; Ответить: johson
Сообщение #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
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
johnmoy
johnmoy
сообщение 12.5.2015, 14:57; Ответить: johnmoy
Сообщение #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

Замечание модератора:
Эта тема была закрыта автоматически ввиду отсутствия активности в ней на протяжении 100+ дней.
Если Вы считаете ее актуальной и хотите оставить сообщение, то воспользуйтесь кнопкой
или обратитесь к любому из модераторов.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Открыть тему
Тема закрыта
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Открытая тема (нет новых ответов) как заслужить право на создание новой темы?
7 writer80 2120 12.3.2024, 22:54
автор: Lumex
Открытая тема (нет новых ответов) <Braga/> Создание Telegram-ботов, web-приложений, крипто-бирж, сайтов.
2 newbraga 1674 10.3.2024, 22:04
автор: newbraga
Открытая тема (нет новых ответов) СОЗДАНИЕ : / САЙтЫ / ЛЕНДЫ / БОТЫ ТГ / ВАЙТЫ / КРЕО / СОФТЫ / ДИЗАЙН [PHP, JS, HTML/CSS] и другое
5 CULA 3291 19.12.2023, 18:55
автор: CULA
Открытая тема (нет новых ответов) Создание и ведение аккаунтов в соцсетях ("В контакте"/Telegram)
Услуги от профессионального журналиста и SMM-менеджера
2 AvtorXXX 1653 13.11.2023, 23:47
автор: AvtorXXX
Открытая тема (нет новых ответов) Создание информационной площадки с доской объявлений
1 xweb 2037 16.1.2023, 16:25
автор: xweb


 



RSS Текстовая версия Сейчас: 28.3.2024, 21:15
Дизайн