2017-02-09 7 views
-1

Мне интересно, можно ли написать ниже sql-запрос как оператор LINQ to Entity. Ниже приведен упрощенный пример реальной мировой проблемы, что я пытаюсь выяснить:Sql Query в Linq to Entity Framework

Select 
c.CustomerID, 
c.CustomerName, 
(Select count(p.ProductID) from Products p 
    where p.CustomerID = c.CustomerID and p.Category = 'HomeAppliance') as ApplianceCount, 
(Select count(p.ProductID) from Products p 
    where p.CustomerID = c.CustomerID and p.Category = 'Furnishing') as FurnishingCount 
from Customer c 
where 
c.CustomerMarket = 'GB' 
order by c.CustomerID desc; 

Любые предложения будут оценены. Производительность LINQ to Entity должна быть рассмотрена, поскольку она потребует получения партии строк.

+0

Пожалуйста, никогда не отправляйте SQL и не запрашивайте конверсию. По крайней мере, покажите модель класса, поэтому видны свойства навигации и множество ассоциаций. Также покажите свои первые усилия. Они разъясняют нам больше, чем вы думаете. –

ответ

3

Нечто подобное (при условии, очевидный контекст):

var res = await (from c in dbCtx.Customers 
       where c.CustomerMarket = "GB" 
       let homeCount = c.Products.Where(p => p.Category = "HomeAppliance").Count() 
       let furnCount = c.Products.Where(p => p.Category = "Furnishing").Count() 
       orderby c.CustomerID descending 
       select new { 
        CustomerID = c.CustomerID, 
        CustomerName = c.CustomerName, 
        ApplianceCount = homeCount, 
        FurnishingCount = furnCount 
       }).ToListAsync(); 

Выполнение LINQ к Сущности должны были бы рассматриваться как это означало бы получение много строк.

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

+0

Спасибо Ричарду. Именно то, что я искал. Мне нужно было что-то вроде «пусть». – NullReference

1

Да, можно:

customers 
    .Where(cust => cust.CustomerMarket == "GB") 
    .Select(cust => new 
    { 
     cust.CustomerId, 
     cust.CustomerName, 
     ApplianceCount = products 
      .Where(prod => prod.CustomerId == cust.CustomerId && prod.Category == "HomeAppliance") 
      .Select(prod => prod.ProductId) 
      .Count(), 
     FurnishingCount = products 
      .Where(prod => prod.CustomerId == cust.CustomerId && prod.Category == "Furnishing") 
      .Select(prod => prod.ProductId) 
      .Count(), 
    }); 

Вот как customers и products являются IQueryable<T> s соответствующего типа.

+0

Спасибо. Но я думаю, что использование «let» упрощает запрос лучше. – NullReference

+0

Я уверен, что они работают одинаково, так что вам не нравится синтаксис метода и синтаксис запросов в целом. Для меня смешение двух в одном и том же месте просто странно, и мое личное предпочтение - синтаксис метода, поэтому я написал его так, но, конечно, это может не относиться к вам :) –