Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Linq запрос к двум List<T> 
V
    Опции темы
TheRam
Дата 6.2.2014, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 6.2.2014

Репутация: нет
Всего: нет



Здравствуйте форумчане.

Вот начал изучать linq и придумал себе задачу, для практики и в ней же застрял:

Есть класс Product с полями ID и Money

Есть два List<Product> list1, list2

Как с помощью linq to object получить набор данных вида ID,list1.Money, list2.Money из list1 и list2 у которых ID равны, но различаются по полю Money и list1.ID нет в list2 (list2.Money в данном случае установить в 0)?

Первую часть с одинаковыми ID, но разными суммами я сделал, а вот как сделать выборку данных, которых нет в list2 с той же проекцией, как и в первой части, что бы их объединить - не получается.


PM MAIL   Вверх
Certain
Дата 6.2.2014, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 235
Регистрация: 18.6.2008
Где: Moscow

Репутация: нет
Всего: 4



Если я правильно понял Вас
Код

class Product
{
    public int id;
    public decimal money;
}
void Main()
{
    List<Product> list1 = new List<Product> {new Product() { id = 1, money = 10.0m},
                                             new Product() { id = 2, money = 20.0m},
                                             new Product() { id = 3, money = 30.0m},
                                             new Product() { id = 4, money = 40.0m},
                                             new Product() { id = 5, money = 50.0m}};
    List<Product> list2 = new List<Product> {new Product() { id = 1, money = 11.0m},
                                             new Product() { id = 2, money = 21.0m},
                                             new Product() { id = 3, money = 30.0m},
                                             new Product() { id = 4, money = 40.0m}};
                                             
    var result = list1.Where (l => list2.Any (li => li.id == l.id && li.money != l.money) 
                              || !list2.Any (li => li.id == l.id))
                      .Select (l => new {Id     = l.id, 
                                         Money1 = l.money, 
                                         Money2 = list2.Where (li => li.id == l.id)
                                                       .DefaultIfEmpty(new Product())
                                                       .FirstOrDefault ().money});    
        result.Dump();
}




Это сообщение отредактировал(а) Certain - 6.2.2014, 20:48
--------------------
Работа программиста и шамана имеет много общего - оба боpмочyт непонятные слова, совершают непонятные действия и не могут объяснить, как оно работает.
PM MAIL ICQ   Вверх
TheRam
Дата 7.2.2014, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 6.2.2014

Репутация: нет
Всего: нет



Спасибо большое, думал не в том направлении, шел по пути объединения трех под запросов.

Но есть еще один вопрос: в оригинале у меня вместо int ID у меня long ID и после выполнения запроса, у меня выводится правильные результаты (9 шт) и еще 128 каких-то данных, с ID = -2147483648 у всех 128 элементов. Вопрос: что это такое и почему их получается 128, когда элементов для сравнения в каждом list > 10 000?
 



Это сообщение отредактировал(а) TheRam - 7.2.2014, 08:51
PM MAIL   Вверх
Certain
Дата 7.2.2014, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 235
Регистрация: 18.6.2008
Где: Moscow

Репутация: нет
Всего: 4



Думаю Вам лучше сюда исходник скинуть...
Проблема может быть
1. В самом списке.
2. В классе Product.
3. В коде, который находится после инициализации списков и до вызова linq запроса.

ID = -2147483648... диапазон типа System.Int32 от -2147483648 до 2147483647  smile 
--------------------
Работа программиста и шамана имеет много общего - оба боpмочyт непонятные слова, совершают непонятные действия и не могут объяснить, как оно работает.
PM MAIL ICQ   Вверх
TheRam
Дата 7.2.2014, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 6.2.2014

Репутация: нет
Всего: нет



Спасибо большое, напоминание диапазона int32 навело на мысль о потери данных при преобразовании типов, что и было. Сначала поле ID у меня  было int, а после обноружил, что нужен long, в результате в одном месте получилось преобразование из long в int, а потом обратно в long smile Теперь все работает как надо smile

А можно еще вопросик: а при использовании list1.Except(list2) можно задать похожую проекцию, как в случае первого варианта?
PM MAIL   Вверх
Certain
Дата 7.2.2014, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 235
Регистрация: 18.6.2008
Где: Moscow

Репутация: нет
Всего: 4



Да, можно, но придётся писать компаратор:
Код

class Product : IEqualityComparer<Product>
        {
            public int id;
            public decimal money;

            public bool Equals(Product p1, Product p2)
            {
                if (Object.ReferenceEquals(p1, p2)) return true;

                if (Object.ReferenceEquals(p1, null) || Object.ReferenceEquals(p2, null))
                    return false;
                return p1.id == p2.id && p1.money == p2.money;
            }

            public int GetHashCode(Product p)
            {
                if (Object.ReferenceEquals(p, null)) return 0;

                int hashProductMoney = p.money.GetHashCode();

                int hashProductId = p.id.GetHashCode();

                return hashProductMoney ^ hashProductId;
            }
        }


и сам запрос:
Код

var result = list1.Except(list2, new Product()).Select (l => new {Id     = l.id, 
                                                                  Money1 = l.money, 
                                                                  Money2 = list2.Where (li => li.id == l.id)
                                                                                .DefaultIfEmpty(new Product())
                                                                                .FirstOrDefault ().money});


Это сообщение отредактировал(а) Certain - 7.2.2014, 14:07
--------------------
Работа программиста и шамана имеет много общего - оба боpмочyт непонятные слова, совершают непонятные действия и не могут объяснить, как оно работает.
PM MAIL ICQ   Вверх
TheRam
Дата 7.2.2014, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 6.2.2014

Репутация: нет
Всего: нет



Спасибо большое!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | LINQ (Language-Integrated Query) | Следующая тема »


 




[ Время генерации скрипта: 0.1298 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.