2016-03-30 2 views
0

Я пытаюсь выполнить этот запрос, но он говорит, что c не определен в этом контексте.LINQ с группировкой и выбором столбцов из другой таблицы: ошибка «не определено в этом контексте»

var carts = from Cart c in Context.Cart 
    join ci in Context.CartItem on c.CartId equals ci.CartId 
    where c.UserIdentity == identity 
    orderby c.CartId descending 
    group c by new { c.CartId } into g 
    select new CartViewModel 
    { 
     Name = c.Name, 
     Active = (c.Active == true) ? "Yes" : "No", 
     IsCheckedOut = (c.IsCheckedOut == true) ? "Yes" : "No", 
     IsExpired = (c.IsExpired == true) ? "Yes" : "No", 
     Items = g.Count() 
    }; 

А вот мой класс

public class CartViewModel 
{ 
    public string Name { get; set; } 
    public string Active { get; set; } 
    public string IsExpired { get; set; } 
    public string IsCheckedOut { get; set; } 
    public int Items { get; set; } 
} 

Что может проблема. Я видел все примеры с выбором, они только выбирают сгруппированные столбцы. Я хочу получить счет из объединенной таблицы и выбрать все остальные столбцы из корзины. Я новичок в .Net.

Примечание: У корзины несколько элементов CartItems. Так что мне нужно подсчет в CartViewModel.

+0

Конечно, это не так: после 'group by' определяется только' g'. См. 'IGrouping '. Зачем вы выбираете группу в первую очередь? –

+0

, если это 'undefined', как я могу« выбрать »и« сопоставить »с моим классом« CartViewModel » –

+0

Нужны ли вам другие агрегаты, чем' Count'? –

ответ

1

После выполнения GroupBy у вас есть доступ к IGrouping<TKey, TElement> через g переменная.

Поскольку вы группируя по Cart ПК, вы можете использовать пункт let принести первую Cart информации, как это:

// ... 
group c by new { c.CartId } into g 
let c = g.FirstOrDefault() 
// ... 

Однако простой Group Join является более подходящим для этого типа запроса, например, :

var carts = from Cart c in Context.Cart 
    join ci in Context.CartItem on c.CartId equals ci.CartId into items 
    where c.UserIdentity == identity 
    orderby c.CartId descending 
    select new CartViewModel 
    { 
     Name = c.Name, 
     Active = (c.Active == true) ? "Yes" : "No", 
     IsCheckedOut = (c.IsCheckedOut == true) ? "Yes" : "No", 
     IsExpired = (c.IsExpired == true) ? "Yes" : "No", 
     Items = items.Count() 
    }; 
0

Обнаружено, как это сделать после прочтения статьи. Вот правильный способ сделать это.

var carts = from Cart c in Context.Cart 
      where c.UserIdentity == identity 
      orderby c.CartId descending 
      select new CartViewModel 
      { 
       Name = c.Name, 
       Active = (c.Active == true) ? "Yes" : "No", 
       IsCheckedOut = (c.IsCheckedOut == true) ? "Yes" : "No", 
       IsExpired = (c.IsExpired == true) ? "Yes" : "No", 
       Items = Context.CartItem.Where(x => x.CartId == c.CartId).Count() 
      }; 

Вместо использования соединения мы можем просто сделать это, используя свойства навигации. Более того, это решение кажется совершенно простым и чистым.
Адрес link.

+0

Не страдает от проблемы N + 1? Я имею в виду, не выполняет ли он другой запрос для каждой записи, найденной в первом запросе? –

0

Используйте Select лямбда-выражение на г, поскольку г имеет сгруппированных запись, а затем выберите нужный столбец в Select лямбда-выражения и применить FirstOrDefault() на нем, чтобы получить результат:

 var carts = from Cart c in Context.Cart 
        join ci in Context.CartItem on c.CartId equals ci.CartId 
        where c.UserIdentity == identity 
        orderby c.CartId descending 
        group c by new { c.CartId } into g 
        select new CartViewModel 
        { 
         Name = g.Select(c => c.Name).FirstOrDefault(), 
         Active = g.Select(c => (c.Active == true) ? "Yes" : "No").FirstOrDefault(), 
         IsCheckedOut = g.Select(c => (c.IsCheckedOut == true) ? "Yes" : "No").FirstOrDefault(), 
         IsExpired = g.Select(c => (c.IsExpired == true) ? "Yes" : "No").FirstOrDefault(), 
         Items = g.Count() 
        }; 
+0

это создает проблему и говорит, что select может применяться только после запроса –