2015-10-09 6 views
2

Мой Linq запросКак я могу объединить эти строки?

List<TopRated> TopRated = (from review in db.ProductReviews 
          group review by review.ProductID into product 
          select new TopRated 
          { 
           ProductName = product.Select(p => p.Products.Name).FirstOrDefault(), 
           Price = product.Select(p => p.Products.Price).FirstOrDefault(), 
           PriceOffer = product.Select(p => p.Products.PriceOffer).FirstOrDefault(), 
           ProductId = product.Key, 
           AverageRating = product.Average(p => p.Rating) 
          }).ToList(); 

может я объединить эти строки в одном?

ProductName = product.Select(p => p.Products.Name).FirstOrDefault(), 
Price = product.Select(p => p.Products.Price).FirstOrDefault(), 
PriceOffer = product.Select(p => p.Products.PriceOffer).FirstOrDefault(), 

Я думаю, что я «добавляю перегрузку», делая что-то вроде выше.

+3

Нет, на самом деле, вы не можете. И нет ничего плохого в том, что эти линии похожи. – Jon

+0

Можете ли вы показать определения своих моделей? (например, ProductReview, Product ..) –

+0

Вы можете использовать метод String.Join() для получения одной строки. Может быть, вы действительно хотите привести результаты в данные. – jdweng

ответ

3

Вы можете использовать пункт let, в котором используется переменная диапазона. На мой взгляд, это создает интуитивный и изящный синтаксис:

var TopRated = (from review in db.ProductReviews 
        group review by review.ProductID into product 
        let firstProduct = product.FirstOrDefault() 
        select new 
        { 
         ProductName = firstProduct.Products.Name, 
         Price = firstProduct.Products.Price, 
         PriceOffer = firstProduct.Products.PriceOffer, 
         ProductId = product.Key, 
         AverageRating = product.Average(p => p.Rating) 
        }).ToList(); 

Для более глубокого анализа, вы можете использовать один из декомпиляторов IL, чтобы увидеть, как каждый из предложенных решений компилируется в IL. Для анализа производительности вы можете протестировать, используя класс StopWatch.

+0

Ударьте меня с парой минут;) –

+0

@GertArnold Да, такие вещи случаются то и дело :) –

+0

О, хорошо. Я всегда забываю о 'let', потому что я стараюсь избегать синтаксиса запроса; Я предпочитаю синтаксис метода самостоятельно. Я дам вам один за это. –

1

Да, вы можете, и в некоторых случаях это может сильно повлиять на производительность вашего запроса.

List<TopRated> TopRated = (from review in db.ProductReviews 
         group review by review.ProductID into product 
         select new 
         { 
          FirstProduct=product.FirstOrDefault(p=>p.Products) 
          ProductId = product.Key, 
          AverageRating = product.Average(p => p.Rating) 
         }).Select(product=>new TopRated { 
          ProductName = product.FirstProduct.Name, 
          Price = product.FirstProduct.Price, 
          PriceOffer = product.FirstProduct.PriceOffer, 
          ProductId = product.ProductId, 
          AverageRating = product.AverageRating 
         }).ToList(); 
1

Вы могли бы сделать что-то вроде этого:

List<TopRated> TopRated = 
    (from review in db.ProductReviews 
    group review by review.ProductID into product 
    select new { ProductId = product.Key, Products = product.FirstOrDefault().Products, AverageRating = product.Average(p => p.Rating) } into topRated 
    select new TopRated 
     { 
      ProductName = topRated.Products.Name, 
      Price = topRated.Products.Price, 
      PriceOffer = topRated.Products.PriceOffer, 
      ProductId = product.Key, 
      AverageRating = topRated.AverageRating 
     }) 
    .ToList(); 

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

0

Вы можете, но лучше сначала сделать группировку и агрегаты, а затем получить информацию о продукте через присоединиться, как это:

var query = (from review in db.ProductReviews 
      group review by review.ProductID into reviews 
      select new { ProductId = reviews.Key, AverageRating = reviews.Average(item => item.Rating) } into summary 
      join product in db.Products on summary.ProductId equals product.Id 
      select new TopRated 
      { 
       ProductName = product.Name, 
       Price = product.Price, 
       PriceOffer = product.PriceOffer, 
       ProductId = product.Id, 
       AverageRating = summary.AverageRating 
      }); 
var sqlQuery = query.ToString(); 
var result = query.ToList(); 

или в данном конкретном случае (только один агрегат) еще проще:

var query = (from product in db.Products 
      select new TopRated 
      { 
       ProductName = product.Name, 
       Price = product.Price, 
       PriceOffer = product.PriceOffer, 
       ProductId = product.Id, 
       AverageRating = product.ProductReviews.Average(review => review.Rating) 
      }); 
var sqlQuery = query.ToString(); 
var result = query.ToList(); 
Смежные вопросы