Я плохо знаком с 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)
});
Заранее спасибо.
Я не совсем уверен, где находится критерии . 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, это должно быть выполнено как единый запрос.
Я не знаю, если он короче, но вы также можете попробовать эту версию, чтобы увидеть, если Это работает лучше с вашим сервером. Я точно не знаю, как эти два ответа превращаются в операторы 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};