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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемма с DefaultIfEmpty() 
V
    Опции темы
BooteR
Дата 19.6.2009, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго времени суток. Скорее всего проблемма не с DefaultIfEmpty(), а с неумением им пользоваться. Гугл перерыл, ничего похожего не нашел, поэтому спрашиваю тут.

Есть несколько табличек в базе. После некоего запроса query получаем таблицу с полями MaterialID и Quantity. Тоесть айди материалла и его необходимое количество. В базе есть таблица Stock. Теперь нужно из query вычесть количество материалов, которое есть на складе. Пробую сделать это таким образом:

Код

var result = from a in query
              select new
             {
                  MaterialId = a.MaterialID,                             
                  Quantity = a.Quantity - dataContext.GetTable<Stock>().Where(n => n.MaterialID == a.MaterialID).Select(n => n.Quantity).DefaultIfEmpty(0).First()
             };


Проблемма в том, что если материала нет на складе, то нужно отнимать 0. Без DefaultIfEmpty() оператор First() выдает exception, потому что входящая последовательность пуста.
А с DefaultIfEmpty(0) выдает exception " Unsupported overload used for query operator 'DefaultIfEmpty' "

Как построить правильно запрос, чтобы небыло проблем когда запись об материале отсутствует в таблице Stock?

Помогите, люди добрые!  smile 
Наперед спасибо
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 05:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Попробуйте вместо метода DefaultIfEmpty (который не "замаплен" в LINQ To SQL) воспользоваться методом SingleOrDefault.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
KelTron
Дата 19.6.2009, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Разовью идею Idsa.

Код

Quantity = a.Quantity - dataContext.GetTable<Stock>()
    .Where(n => n.MaterialID == a.MaterialID)
    .Select(n => n.Quantity).SingleOrDefault() ?? 0



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



KelTron, что есть выражение "?? 0"?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
KelTron
Дата 19.6.2009, 07:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну есть такой оператор в шарпе)

Ниже два эквивалентных куска кода:

Код

(s != null) ? s : 0;


Код

s ?? 0;



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



KelTron, а зачем он здесь? SingleOrDefault, если не найдет запись, вернет 0.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
KelTron
Дата 19.6.2009, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хм, да, ты прав...как то не обратил внимания, что там не класс.



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Итого:
Код

Quantity = a.Quantity - dataContext.GetTable<Stock>()
    .Where(n => n.MaterialID == a.MaterialID)
    .Select(n => n.Quantity).SingleOrDefault();


KelTron, спасибо за оператор ?? smile Странно, но ни разу его раньше не встречал.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
KelTron
Дата 19.6.2009, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



На здоровье)


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
BooteR
Дата 19.6.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Попробовал с SingleOrDefault():

Код

var result = from a in query
                   select new
                   {
                         MaterialId = a.MaterialID,
                         Quantity = a.Quantity - dataContext.GetTable<Stock>().Where(n => n.MaterialID == a.MaterialID).Select(n => n.Quantity).SingleOrDefault()
                   };


Получил exception: "The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type"

Причем вот это работает правильно:

Код

foreach (var t in query)
{
       System.Diagnostics.Debug.WriteLine(
            t.MaterialID.ToString() + " - " +
            (t.Quantity - dataContext.GetTable<Stock>().Where(n => n.MaterialID == t.MaterialID).Select(n => n.Quantity).SingleOrDefault()).ToString()
       );
}



В чем проблемма? Я вообще запутался :(
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



BooteR, приведите схему таблицы Stock


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
BooteR
Дата 19.6.2009, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот:

user posted image
PM MAIL   Вверх
Idsa
Дата 19.6.2009, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



MaterialId, оказывается, не первичный ключ. Тогда не понимаю смысл этого запроса.
Исключение, видимо, вылетает из-за того, что dataContext.GetTable<Stock>().Where(n => n.MaterialID == t.MaterialID) содержит более одного элемента. Раз так, стоит заменить SingleOrDefault на FirstOrDefault.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
BooteR
Дата 19.6.2009, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я уже не помню почему я не сделал MaterialId первичным ключем, то двух записей с одинаковым MaterialId в таблице нет. Сделал MaterialId первичным ключем, выдает тот же exception. Заменил SingleOrDefault на FirstOrDefault, все та же проблема  smile 
Почему же foreach работает нормально?
PM MAIL   Вверх
BooteR
Дата 19.6.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Сделал так:

Код

(dataContext.GetTable<Stock>().Where(n => n.MaterialID == a.MaterialID).Select(n => n.Quantity).FirstOrDefault() == null) ? 0 : dataContext.GetTable<Stock>().Where(n => n.MaterialID == a.MaterialID).Select(n => n.Quantity).FirstOrDefault()


Некрасиво, но работает. А вообще странно как то...

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


 




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


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

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