2016-04-11 3 views
3

LINQ У меня есть запрос LINQ, какпереключатель случай внутри

var tmp = (from t in db.sometable 
      where (bunch of conditions) 
      group t by new { t.somefield} into g 
      select new 
      {        
       Name = g.Key.someobject.Name, 
       xColor = g.Sum(a => (int?)a.LineItems.Where(m => m.Product == "x" && m.Color == true) 
                .Sum(m => m.Quantity)), 
       xBW = g.Sum(a => (int?)a.LineItems.Where(m => m.Product == "x" && m.Color == false) 
                .Sum(m => m.Quantity))  
      }) 

Теперь я хочу, чтобы оптимизировать этот запрос. Если бы я должен был написать хранимую процедуру, я бы написал некоторые вещи, как:

if(a.LineItems.Product == 'x') 
{ 
    if(m.Color == true) 
    xColor++; 
    else 
    xBW++; 
} 

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

+1

Опечатки в вашем Запрос LINQ? Вы имели в виду это 'xColor = g.Sum (a => (int?) A.LineItems.Where (m => m.Product ==" x "&& m.Color == true) ...'? –

+0

@GrantWinney: Да, спасибо за то, что указали это, теперь его исправили. –

+0

Вы можете добавить кейс коммутатора, введя фигурные скобки внутри запроса linq и обновляя глобальную переменную, используя его как окончательное значение, но я не уверен, как это будет эффективно, так как это тоже будет обрабатывать каждый внутри IEnumerable , созданный из-за Groupby –

ответ

0

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

1

Проверьте этот простой фрагмент кода в Linqpad, который делает так, как вы ожидаете, для работы в визуальной студии, удалите вызов метода Dump. Я упростил структуру класса немного для простого демы, это просто POCO, а не complex type содержащих другой list внутри

void Main() 
{ 
    var testList = Test.CreateList(); 

    var tmp = (from t in testList 
       group t by new { t.Name } into g 
       select new 
       { 
        Name = g.Key.Name, 
        xColor = g.Sum(a => 
        { 
         if (a.Product == "x" && a.Color == true) 
          return a.Quantity; 
         return 0; 
        }), 
        xBW = g.Sum(a => 
        { 
         if (a.Product == "x" && a.Color == false) 
          return a.Quantity; 
         return 0; 
        }) 
       }); 

    tmp.Dump(); 
} 

public class Test 
{ 
    public string Name { get; set; } 

    public string Product { get; set;} 

    public bool Color { get; set;} 

    public int? Quantity { get; set;} 

    public static List<Test> CreateList() 
    { 
     return new List<Test>() 
     { 
      new Test {Name="A",Color = true,Product="x",Quantity=5}, 
      new Test {Name="A",Color = true,Product="x",Quantity=5}, 
      new Test {Name="A",Color = true,Product="x",Quantity=5}, 
      new Test {Name="B",Color = true,Product="x",Quantity=5}, 
      new Test {Name="B",Color = true,Product="x",Quantity=5}, 
      new Test {Name="B",Color = true,Product="x",Quantity=5}   
     }; 
    } 
} 

Однако это является ли эффективным или нет до сих пор можно обсуждать

+0

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

Смежные вопросы