2015-10-02 2 views
1

Я думаю, что я сделал запрос очень многократно, и мне было интересно, можете ли вы помочь мне понять, как это сделать лучше. Я делаю Join и GroupBy в зависимости от EnumDateFilter. Можете ли вы мне помочь, пожалуйста, сократите код, насколько это возможно?Linq Join and GroupBy refactor

Большое спасибо!

foreach (Client client in listClient){ 
    var books = _servBook.GetBooks(BeginDate, EndDate, ClientId).ToList(); 

    switch (enumDateFilter) 
    { 
     case EnumDateFilter.Today: 
     case EnumDateFilter.OneDay: 
      { 
       books.Join(
        dates, 
        bk => new { bk.Date.Hour, bk.Date.Day, bk.Date.Month, bk.Date.Year }, 
        cd => new { cd.Date.Hour, cd.Date.Day, cd.Date.Month, cd.Date.Year }, 
        (bk, chart) => new { bk, chart.Data } 
       ) 
       .GroupBy(a => new 
       { 
        a.bk.Date.Hour, 
        a.bk.Date.Day, 
        a.bk.Date.Month, 
        a.bk.Date.Year, 
        a.Data 
       }) 
       .Select(
        a => 
        { 
         a.Key.Data[client.Name] = a.Count().ToString(); 
         return a; 
        } 
       ).ToList(); 
      } 
      break; 

     case EnumDateFilter.OneWeek: 
     case EnumDateFilter.OneMonth: 
     case EnumDateFilter.LastWeek: 
     case EnumDateFilter.LastMonth: 
      { 
       books.Join(
        dates, 
        bk => new { bk.Date.Day, bk.Date.Month, bk.Date.Year }, 
        cd => new { cd.Date.Day, cd.Date.Month, cd.Date.Year }, 
        (bk, chart) => new { bk, chart.Data } 
       ) 
       .GroupBy(a => new 
       { 
        a.bk.Date.Day, 
        a.bk.Date.Month, 
        a.bk.Date.Year, 
        a.Data 
       }) 
       .Select(
        a => 
        { 
         a.Key.Data[client.Name] = a.Count().ToString(); 
         return a; 
        } 
       ).ToList(); 

       break; 
      } 

     case EnumDateFilter.ThreeMonths: 
     case EnumDateFilter.SixMonths: 
     case EnumDateFilter.OneYear: 
     case EnumDateFilter.LastThreeMonths: 
     case EnumDateFilter.LastSixMonths: 
     case EnumDateFilter.LastYear: 
      { 
       books.Join(
        dates, 
        bk => new { bk.Date.Month, bk.Date.Year }, 
        cd => new { cd.Date.Month, cd.Date.Year }, 
        (bk, chart) => new { bk, chart.Data } 
       ) 
       .GroupBy(a => new 
       { 
        a.bk.Date.Month, 
        a.bk.Date.Year, 
        a.Data 
       }) 
       .Select(
        a => 
        { 
         a.Key.Data[client.Name] = a.Count().ToString(); 
         return a; 
        } 
       ).ToList(); 
       break; 
      } 

     case EnumDateFilter.SinceBeginning: 
      { 
       books.Join(
        dates, 
        bk => new { bk.Date.Year }, 
        cd => new { cd.Date.Year }, 
        (bk, chart) => new { bk, chart.Data } 
       ) 
       .GroupBy(a => new 
       { 
        a.bk.Date.Year, 
        a.Data 
       }) 
       .Select(
        a => 
        { 
         a.Key.Data[client.Name] = a.Count().ToString(); 
         return a; 
        } 
       ).ToList(); 
       break; 
      } 
    } 
+0

Что вы имеете в виду под «заменой выражениями»? – poke

+0

Лямбда Выражение, но я не уверен, что это возможно – specialk

+0

С какой целью? Как вы думаете, что лямбда-выражения позволяют вам здесь? – poke

ответ

0

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

struct TimeDescriptor{ 
    public int Year; 
    //TODO: Put other fields 
} 

Это затем позволит вам учитывать некоторые из лямбда-выражений, таких как

Expression<Func<Book, TimeDescriptor>> bookSelector = b => new TimeDescriptor{Year = b.Date.Year, ...} 
Expression<Func<DateType, TimeDescriptor>> dateSelector = d => new TimeDescriptor{Year = d.Date.Year} 

, которые вы могли бы использовать в вашем LINQ, такие как

books.Join(dates, bookSelector, dateSelector, ...) 

Теперь ваш коммутатор можно свести к выбору соответствующих селекторов, и вы можете написать основной запрос вне коммутатора. Пример:

Expression<Func<Book, TimeDescriptor>> bookSelector; 
Expression<Func<DateType, TimeDescriptor>> dateSelector; 

switch((enumDateFilter) 
{ 
    case EnumDateFilter.Today: 
    case EnumDateFilter.OneDay: 
     bookSelector = ...; 
     dateSelector = ...; 
     break; 
    ... 
} 

return books.Join(dates, bookSelector, dateSelector, ...) 

Надеюсь, это поможет вам получить некоторые идеи.

+0

Спасибо, Рональд за ваш ответ! Помогает много! – specialk