2013-09-23 3 views
3

Мне пришлось создать запрос LINQ, соединяющий 3 IEnumerable (2 типа данных, один список). Я также должен «внешние соединения» мои 2 соединения.C# - LINQ - Выступления между 2 типами запроса

Мне очень нравится вторая, потому что намного более лидируема и сопоставима с SQL. Но я столкнулся с проблемами производительности (в 3 раза больше) по сравнению с первым, но менее быстрым.

Может кто-нибудь объяснить мне, что я могу сделать для оптимизации второго запроса, а также почему они так сильно отличаются друг от друга, но возвращают одни и те же данные (я новичок в LINQ и с трудом понимаю каждое LINQ- TO-SQL/LAMBDA/SAMBA subtilities

старый, очень быстро, но менее lisible

var Detailled_payroll = 
     from MainData in dt_BasicPayrollData.AsEnumerable() 
      //joining (Externalize later...) with a list of days 
      join MyDays in gdt_Liste_JourFérié 
       on MainData.Field<DateTime>("DENTREE") equals MyDays 
        into MyDays_join //why? 
      //joining (Externalize later...) with a list (datatable) of things 
      join MyFilter in gdt_MyFilter.AsEnumerable() 
       on MainData.Field<string>("KEY") equals MyFilter.Field<string>("KEY") 
        into MyFilter_join //why? 

      //I think we "outer join" here, forcing the existing of a missing join        
      from MyDays in MyDays_join.DefaultIfEmpty() 
      from MyFilter in MyFilter_join.DefaultIfEmpty() 

      let tmp = MainData.Field<string>("CEmploye") //dont remember why.. 

      select new Blabla() 
      { 
       EmpNumber=MainData.Field<string>("NoEmploye"), 
       IsInSpecialDays = MyDays == Default(DateTime) ? "NO" : "YES", 
       KeyWasFound = MyFilter == null ? "NO" : "YES" 
      } 

а вот "новый" один:

var Detailled_payroll = 
     from MainData in dt_BasicPayrollData.AsEnumerable() 
     //joining (and externalize...) with a list (datatable) of things 
     from MyFilter in MyGlobalVariable.gdt_FiltreEnCours.AsEnumerable() 
      .Where(x => x.Field<string>("KEY") == MainData.Field<string>("KEY")) 
      .DefaultIfEmpty() 
     //joining (and externalize...) with a list (List<DateTime>) of days 
     from MyDays in gdt_Liste_JourFérié 
      .Where(x => x == MainData.Field<DateTime>("DENTREE")) 
      .DefaultIfEmpty() 

     select new Blabla() 
      { 
       EmpNumber=MainData.Field<string>("NoEmploye"), 
       IsInSpecialDays = MyDays == Default(DateTime) ? "NO" : "YES", 
       KeyWasFound = MyFilter == null ? "NO" : "YES" 
      } 
  • «старый» запрос возвращает результаты за 3 секунды.
  • «новый» запрос возвращает результаты за 10 секунд.

Оба имеют одинаковые результирующие данные.

Любые идеи?

+0

Ответы на ваши 'why?' - потому что вы хотите выполнить левое соединение. –

+1

Разве это не второй трек-крест с тремя таблицами, где первый - это левое соединение? –

ответ

4

Одним словом, в первом случае вы присоединились, во втором у вас есть декартово произведение , затем вы его фильтруете.

+0

Это не просто одно слово. Но это правильный ответ. – Servy

+0

@Servy Возможно, кому-то нужно более подробное объяснение. –

+3

Я не говорю, что это должно быть одно слово, я просто говорю, что ваш «одним словом» ведет ... неточно. – Servy

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