Группа LINQ вопросом месяца

Я плохо знаком с LINQ к SQL, и я хотел бы знать, как достигнуть чего-то вроде этого в LINQ:

        Month   Hires  Terminations   
        Jan      5       7
        Feb      8       8
        Marc     8       5

У меня есть это до сих пор, и я думаю, что существует что-то не так с ним, но я не уверен:

from term1 in HRSystemDB.Terminations
group term1 by new { term1.TerminationDate.Month, term1.TerminationDate.Year } into grpTerm
select new HiresVsTerminationsQuery
{
  Date = Criteria.Period,
  TerminationsCount = grpTerm.Count(term => term.TerminationDate.Month == Criteria.Period.Value.Month),
  HiresCount = (from emp in HRSystemDB.Persons.OfType<Employee>()
               group emp by new { emp.HireDate.Month, emp.HireDate.Year } into grpEmp
               select grpEmp).Count(e => e.Key.Month == Criteria.Period.Value.Month)
});

Заранее спасибо.

5
задан jasonco 20 January 2010 в 21:41
поделиться

2 ответа

Я не совсем уверен, где находится критерии . Deveriod значение поступает из вашего примерного запроса.

Однако я думаю, что вы пытаетесь прочитать как нанимальные, так и для всех доступов для всех доступных месяцев (а затем вы можете легко отфильтровать его). Ваш запрос может пойти не так, если первая таблица (расторжение) не включала никаких записей на определенный месяц (скажем, может). Тогда выберите пункт , не будет вызван с «May» в качестве параметра вообще и даже если у вас были некоторые данные во второй таблице (представляющие нанимать), то вы не сможете найти его Отказ

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

var terms = from t in HRSystemDB.Terminations 
            select new { Month = t.TerminationDate.Month, 
                         Year = term1.TerminationDate.Year,
                         IsHire = false };
var hires = from emp in HRSystemDB.Persons.OfType<Employee>() 
            select new { Month = emp.HireDate.Month, 
                         Year = emp.HireDate.Year 
                         IsHire = true };

// Now we can merge the two inputs into one
var summary = terms.Concat(hires);

// And group the data using month or year
var res = from s in summary 
          group s by new { s.Year, s.Month } into g
          select new { Period = g.Key, 
                       Hires = g.Count(info => info.IsHire),  
                       Terminations = g.Count(info => !info.IsHire) }

При взгляде на код теперь я уверен, что есть немного более короткого способа написать это. С другой стороны, этот код должен быть довольно читаемым, что выгодно. Также обратите внимание, что не имеет значения, что мы разделим код в пару подпросов. Благодаря ленивой оценке Linq к SQL, это должно быть выполнено как единый запрос.

6
ответ дан 14 December 2019 в 01:08
поделиться

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

var terms = 
    from t in Terminations
    group t by new {t.Month, t.Year} into g
    select new {g.Key, Count = g.Count()};

var hires = 
    from p in Persons
    group p by new {p.Month, p.Year} into g
    select new {g.Key, Count = g.Count()};

var summary = 
    from t in terms
    join h in hires on t.Key equals h.Key
    select new {t.Key.Month, t.Key.Year, 
        Hires = h.Count, Terms = t.Count};
3
ответ дан 14 December 2019 в 01:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: