Проблемы с запросом linq - PullRequest
0 голосов
/ 26 декабря 2018

Я пытаюсь получить определенные значения, организованные по месяцам, из моей базы данных с помощью запроса Linq, но у меня возникли небольшие проблемы, и я не знаю, почему это может произойти.

Данныеорганизовано так:

A Ticket имеет много продуктов, а Worker имеет много билетов, а в Shop много рабочих, иАдминистратор Пользователь имеет много магазинов.Существует таблица под названием Shops_Workers, где я могу создавать отношения с магазинами и работниками.У Ticket есть поле с датой, которую он создал, и другое поле с именем Points , которое дает целочисленное значение для этого билета.Мне нужно получить сумму всех баллов всех билетов, созданных на одного работника для всех магазинов, в которых есть пользователь в месяц.

Я использую EntityFramework и попытался сделать запрос linq для получения всех данных., поэтому я создал несколько полей DateTime для получения месяцев и выполнил подзапросы в своем запросе linq, но я не знаю, может ли это работать должным образом.

 Int32? admin = getCurrentUser();
 DateTime TmpYear = DateTime.Now;

 var result = (from s in _db.Shops
                      join t in db.Tickets on s.IdShop equals t.IdTicket
                      join sw in db.Shop_Worker on s.IdShop equals sw.IdShop
                      join u in db.Users on sw.IdUser equals u.IdUser
                      where u.IdUser == admin
                      select new {
                          Jan = s.Tickets.Where(x => x.SellDate.Value.Month == this.Jan.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Feb = s.Tickets.Where(x => x.SellDate.Value.Month == this.Feb.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Mar = s.Tickets.Where(x => x.SellDate.Value.Month == this.Mar.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Ap = s.Tickets.Where(x => x.SellDate.Value.Month == this.Ap.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          May = s.Tickets.Where(x => x.SellDate.Value.Month == this.May.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Jun = s.Tickets.Where(x => x.SellDate.Value.Month == this.Jun.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Jul = s.Tickets.Where(x => x.SellDate.Value.Month == this.Jul.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Au = s.Tickets.Where(x => x.SellDate.Value.Month == this.Au.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Sep = s.Tickets.Where(x => x.SellDate.Value.Month == this.Sep.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Oct = s.Tickets.Where(x => x.SellDate.Value.Month == this.Oct.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Nov = s.Tickets.Where(x => x.SellDate.Value.Month == this.Nov.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                          Dec = s.Tickets.Where(x => x.SellDate.Value.Month == this.Dec.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum(),
                      });

У меня есть System.Collections.ListDictionaryInternalошибка с сообщением:

Преобразование в тип значения 'System.Int32' не выполнено, поскольку материализованное значение равно нулю.Либо универсальный параметр типа результата, либо запрос должен использовать обнуляемый тип.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Появилось несколько проблем:

 Int32? admin = getCurrentUser();

Утверждают, что вы вернули пользователя-администратора, прежде чем пытаться использовать его в запросе, затем в запросе используйте admin.Value.

var result = (from s in _db.Shops
                      join t in db.Tickets on s.IdShop equals t.IdTicket

Здесь магазины и билеты соединяются под ключ.(IdShop to IdTicket) Поскольку похоже, что ваш магазин сопоставлен с коллекцией билетов, эти явные объединения не нужны.Лично я не использую синтаксис linq-QL, так как нахожу, что беглые методы более просты в использовании и структурированы, а смешивание этих двух вопросов просто сбивает с толку.сначала получить соответствующие данные, сгруппированные по месяцам, а затем преобразовать их в требуемую структуру данных.Linq великолепен, однако попытка сделать слишком много в одном выражении может усложнить понимание.Могут быть упрощения, но можно надеяться, что это даст вам некоторые идеи о том, как справиться с преобразованием.

var totalTickets = _db.Shops.Where(s => s.ShopWorkers.Any(sw => sw.IdUser == admin.Value))
    .SelectMany(s => s.Tickets.Where(t => t.SellDate.HasValue && t.SellDate.Value.Year == tmpYear.Year))
    .Select(t => new {Month = t.SellDate.Value.Month, t.Points})
    .GroupBy(x => x.Month)
    .Select(x => new {Month = x.Key, TotalPoints = x.Sum(g => g.Points)).ToList();

Я извлекаю это из памяти, так что, возможно, потребуется некоторая настройка, но сутьчтобы вытащить магазины, в которых работники содержат текущего пользователя, затем выберите все билеты для этих магазинов на определенный год, из которого мы хотим получить месяц и значение баллов.Мы группируем по месяцам, затем выбираем эту группу (месяц) с суммой баллов для этой группы.Вы должны получить список за каждый месяц, когда были проданы билеты.Это не будет включать месяцы, когда билеты не были проданы, поэтому вам нужно будет объединить в ноль месяцев, чтобы получить полный список.Исходя из этого, вы должны иметь возможность заполнять структуру значением каждого месяца как свойство.

0 голосов
/ 26 декабря 2018

Думаю, проблема здесь:

Jan = s.Tickets.Where(x => x.SellDate.Value.Month == this.Jan.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => e.Points).Sum()

Если у вас нет данных для этого условия, SQL вернет ноль, но свойство Jan не равно нулю, поэтому измените запрос следующим образом:

Jan = s.Tickets.Where(x => x.SellDate.Value.Month == this.Jan.Month && x.SellDate.Value.Year == TmpYear.Year).Select(e => (int?)e.Points).Sum() ?? 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...