Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Новый топик    Ответить
 LINQ запрос к классам  [new]
is1077
Member

Откуда:
Сообщений: 22
Не могу найти подходящий пример, везде примеры приводят с 1 массивом :(
Вот простенький пример, есть классы:
   
class Sector
{
        public string _sectorName;
        public List<float> _dataFloat = null;
        public Sector()
        {
            _dataFloat = new List<float>();
        }
}
class Sayt
{
        public string _saytName;
        public List<Sector> _dataSector = null;
        public Sayt()
        {
            _dataSector = new List<Sector>();
        }
}

Есть массив
Sayt[] sayt;
Например мне нужен результат массив классов Sayt, где в классе Sector значения dataFloat > 14
Тк только вчера начал изучать, в голову пришел вариант:
           var ss = from c in sayt
                     from x in c._dataSector
                     from v in x._dataFloat
                     where (v > 14)
                     select new 
                     {
                         c._saytName,
                         x._sectorName,
                         v
                     }
foreach (var c in ss)
            {
                Console.Write(c._saytName + "\n");
                Console.Write("   " + c._sectorName + "\n");
                Console.Write("      " + c.v + "\n");
            }
Но результат выборки не тот что хочется,
получаем информацию вида :
sayt0
sec0
15
sayt0
sec1
18
sayt0
sec1
115
sayt1
sec0
11
sayt1
sec1
19
sayt1
sec1
110
А хочется такую:
sayt0
sec0
15
sec1
18
115
sayt1
sec0
11
sec1
19
110


Как запросить такой вариант ?
24 фев 09, 22:13    [6856346]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5951
is1077
Не могу найти подходящий пример, везде примеры приводят с 1 массивом :(

вот полезная штука
25 фев 09, 18:00    [6860632]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
is1077
Member

Откуда:
Сообщений: 22
Странно что еще никто не ответил :) (может я вопрос не очень точно задал, или технология новая и не все хотят ей мозги забивать :))но это ничего , я сам разобрался , оказывается что можно делать иерархические запросы.
вот такой пример получился:
 var ss = from c in sayt
                     select new
                     {
                         SaytName = c._saytName,
                         SecName = (from x in c._dataSector 
                                    select new 
                                    {
                                        x._sectorName,
                                        data =  (from v in x._dataFloat
                                        where (v > 14) select v)
                                    }
                                    )

                     };

            foreach (var c in ss)
            {
                Console.Write(c.SaytName + "\n");
                foreach (var m in c.SecName)
                {
                    Console.Write("   " + m._sectorName + "\n");
                    foreach (var t in m.data)
                    {
                        Console.Write("      " + t + "\n");
                    }
                }
            }
Может кому понадобится, хотя возможно есть варианты проще, но я пока о них не знаю :)
Если у кого идеи есть как сделать лучше , отпишитесь ;)
28 фев 09, 09:23    [6872993]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5951
1. нет необходимости присваивать null.
2. Если выкладываете код, в котором посредством LINQ хотите вытащить информацию, интересующую вас, то не ленитесь выкладывать и код, который наполняет данными ваши классы, дабы было на чем тестировать результат запроса. Ибо вряд ли кто-то будет сидеть и вручную вбивать данные с тем, чтобы построить нужный вам запрос.
3. Подозреваю, что написать более коротко можно. Например так:
Sayt[] ss_result = ss.AsEnumerable().Where(a => a._dataSector.Where(m => m._dataFloat<14).Count() > 0).ToArray();
правда код я не тестировал, ибо вбивать туеву хучу данных для теста лень. Если бы вы выложили их - тогда был бы точный вариант.
4. Лучше сразу привыкать использовать точечную нотацию, т.к. в том виде, что составили вы, далеко не всякий запрос можно составить. В точечной такой проблемы нет.
5. Этот форум вообще можно назвать мёртвым, ибо сюда мало кто заглядывает. имхо.
6. Переходите на IEnumerable<T>, к чему юзать Array? имхо.
28 фев 09, 13:03    [6873197]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
is1077
Member

Откуда:
Сообщений: 22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication4
{
    class Sector
    {
        public string SectorName { get; set; }
        public List<float> DataFloat { get; set; }
        public Sector() { }
    }
    class Sayt
    {
        public string SaytName { get; set; }
        public List<Sector> DataSector { get; set; }
        public Sayt() { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Заполняем
            var sectors0 = new List<Sector> 
            { 
                new Sector(){SectorName = "sec0", DataFloat = new List<float>{ 1,2,15} },
                new Sector(){SectorName = "sec1", DataFloat = new List<float>{ 1,18,115} }
            };
            var sectors1 = new List<Sector> 
            { 
                new Sector(){SectorName = "sec0", DataFloat = new List<float>{ 1,2,111} },
                new Sector(){SectorName = "sec1", DataFloat = new List<float>{ 1,19,110} }
            };
            
            var sayts = new List<Sayt>
            {
                new Sayt(){SaytName = "sayt0",DataSector = sectors0},
                new Sayt(){SaytName = "sayt1",DataSector = sectors1}
            };
          
            // Мой вариант выборки 
            var sRez1 = from c in sayts
            select new
            {
                SaytName = c.SaytName,
                DataSector = (from x in c.DataSector
                select new
                {
                    x.SectorName,
                    DataFloat = (from v in x.DataFloat
                            where (v > 14)
                            select v)
                })
            };

            foreach (var c in sRez1)
            {
                Console.WriteLine(c.SaytName);
                foreach (var m in c.DataSector)
                {
                    Console.WriteLine("   " + m.SectorName);
                    foreach (var t in m.DataFloat)
                    {
                        Console.WriteLine("      " + t);
                    }
                }
            }
            //Вариант с точкой (Не работает :( Будут выведены все данные)
            var sRez2 = sayts.Where(a => a.DataSector.Where(m => m.DataFloat.Where(t => t > 14).Count() > 0).Count() > 0);
            foreach (var c in sRez2)
            {
                Console.Write(c.SaytName + "\n");
                foreach (var m in c.DataSector)
                {
                    Console.Write("   " + m.SectorName + "\n");
                    foreach (var t in m.DataFloat)
                    {
                        Console.Write("      " + t + "\n");
                    }
                }
            }
            // Хотя даже если упростить , например нужны сектора "sec0", выведены будут все данные
            var sRez3 = sayts.Where(a => a.DataSector.Where(m => m.SectorName == "sec0").Count() > 0);
            foreach (var c in sRez3)
            {
                Console.Write(c.SaytName + "\n");
                foreach (var m in c.DataSector)
                {
                    Console.Write("   " + m.SectorName + "\n");
                    foreach (var t in m.DataFloat)
                    {
                        Console.Write("      " + t + "\n");
                    }
                }
            }
        }
    }
}
28 фев 09, 17:26    [6873495]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
is1077
Member

Откуда:
Сообщений: 22
Compositum,
Учел все замечания , вывел полный листинг программы +
немного изменил классы
С точечной нотацией не разобрался еще, в процессе ... :)
А какой форум не мертвый ?
Жду еще вариантов :)
28 фев 09, 17:31    [6873505]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5951
is1077
Compositum,
Учел все замечания , вывел полный листинг программы +
немного изменил классы
С точечной нотацией не разобрался еще, в процессе ... :)
А какой форум не мертвый ?
Жду еще вариантов :)

Сегодня уже смотреть не в состоянии. Гляну завтра. Касательно НЕ мёртвого форума - тут не подскажу, поскольку не искал альтернативы, тут вам гугл в помощь, однако не думаю, что найдутся "более живые", разве что на форумах майкрософта (у них тоже есть ветка форума для LINQ).
Как правило, люди "сидят" в форумах типа "C#.NET" - так сказать в более "родных" форумах. Посему сюда заглядывают редко.
28 фев 09, 23:02    [6873885]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5951
Сел глянул...
На всякий случай уточняю то, как я понял ваш вопрос:
автор
Например мне нужен результат массив классов Sayt, где в классе Sector значения dataFloat > 14

Т.е. Если в массиве DataFloat есть хоть одно число > 14, то Sector нужно выбрать и далее - если есть хоть один выбраный Sector, то следует выбрать и Sayt.

Согласно понятому мной правлю ваш код и показываю вариант запроса в точечной форме:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication4
{
    class Sector
    {
        public string SectorName { get; set; }
        public List<float> DataFloat { get; set; }
        public Sector() { }
    }
    class Sayt
    {
        public string SaytName { get; set; }
        public List<Sector> DataSector { get; set; }
        public Sayt() { }
    }


    class Program
    {
        static void Main(string[] args)
        {
            // Заполняем
           List< Sector> sectors0 = new List<Sector> //Если вам точно известен тип - указывайте его, а не var
            { 
                new Sector(){SectorName = "sec0", DataFloat = new List<float>{ 5,4,5} },
                new Sector(){SectorName = "sec0_1", DataFloat = new List<float>{ 6,8,4} },
                new Sector(){SectorName = "sec0_2", DataFloat = new List<float>{ 6,8,4} },
                new Sector(){SectorName = "sec0_3", DataFloat = new List<float>{ 6,8,4} }
            };
           List<Sector> sectors1 = new List<Sector> 
            { 
                new Sector(){SectorName = "sec1", DataFloat = new List<float>{ 15,4,5} },
                new Sector(){SectorName = "sec1_1", DataFloat = new List<float>{ 6,8,4} },
                new Sector(){SectorName = "sec1_2", DataFloat = new List<float>{ 6,8,4} },
                new Sector(){SectorName = "sec1_3", DataFloat = new List<float>{ 6,8,4} }
            };
           List<Sector> sectors2 = new List<Sector> 
            { 
                new Sector(){SectorName = "sec2", DataFloat = new List<float>{ 5,4,5} },
                new Sector(){SectorName = "sec2_1", DataFloat = new List<float>{ 6,8,4} },
                new Sector(){SectorName = "sec2_2", DataFloat = new List<float>{ 6,80,4} },
                new Sector(){SectorName = "sec2_3", DataFloat = new List<float>{ 6,8,4} }
            };

            List<Sayt> sayts = new List<Sayt>//Если вам точно известен тип - указывайте его, а не var
            {
                new Sayt(){SaytName = "sayt_0",DataSector = sectors0},
                new Sayt(){SaytName = "sayt_1",DataSector = sectors1},
                new Sayt(){SaytName = "sayt_2",DataSector = sectors1}
            };

            //Вариант запроса by Compositum:
            List<Sayt> ss_result = sayts.Where(a => a.DataSector.Where( b => b.DataFloat.Where( c => c > 14F).Count() > 0).Count()>0).ToList();           

            Console.WriteLine("===============================");
            foreach (Sayt item in ss_result)
	{
                Console.WriteLine(item.SaytName);
	}
            Console.WriteLine("===============================");
          
            Console.Read();
        }
    }
}
1 мар 09, 00:42    [6873985]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5951
п.с. составленная мною форма запроса сильно напоминает мне LISP (когда-то писал не нем немножко для AutoCAD). Вспомнилось в связи с тем, что часть запроса нужно читать "изнутри к наруже" - как в Лиспе, что не совсем удобно для тех, кто не писал на подобных языках ранее (нужно привыкнуть к синтаксису)...
1 мар 09, 00:46    [6873988]     Ответить | Цитировать Сообщить модератору
 Re: LINQ запрос к классам  [new]
Pasionario
Member

Откуда:
Сообщений: 213
var sRez = sayts.Select(
                s =>
                    new
                    {
                        SaytName = s.SaytName,
                        DataSector = s.DataSector.Select(
                            ds => new
                            {
                                ds.SectorName,
                                DataFloat = ds.DataFloat.Where(df => df > 14)
                            })
                    }
            );
вот "точечный" эквивалент, имхо, менее читабельный
2 мар 09, 00:31    [6874987]     Ответить | Цитировать Сообщить модератору
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Ответить