我想知道是否有人可以帮助我为以下场景生成linq查询。
以下是具有相关属性的类:
public class Employee
{
IList<Employee> DirectReports { get; set;}
IList<BonusPlan> BonusPlans { get; set;}
BonusPlanTemplate BonusPlanTemplate { get; set;}
}
public class BonusPlan
{
FiscalPeriod FiscalPeriod { get; set; }
Employee Employee { get; set;}
}
我正在尝试创建一个方法:
IEnumerable<Employee> GetDirectReportsWithoutBonusPlansCreatedForFiscalPeriod(FiscalPeriod fiscalPeriod)
所以基本上我有这个来获得特定财政期间奖金计划的直接报告:
var query = from dr in DirectReports
from bp in dr.BonusPlans
where bp.Employee.BonusPlanTemplate != BonusPlanTemplate.Empty &&
bp.FiscalPeriod==fiscalPeriod
select dr;
IList<Employee> directReportsWithBonusPlansCreated = query.ToList();
然后我得到所有应该有奖励计划设置的DirectReports(通过分配BonusPlanTemplate表示),这些不在上一个查询的列表中。
var query2 = from dr in DirectReports
where dr.BonusPlanTemplate != BonusPlanTemplate.Empty &&
!directReportsWithBonusPlansCreated.Contains(dr)
select dr;
这会产生正确的结果,但似乎必须有另一种方式。我不确定是否需要分两步完成。有人可以帮我组合这两个linq查询,并可能使它更有效。我对Linq的经验相对较少。
答案 0 :(得分:3)
您是否因任何其他原因需要第一个查询?如果没有,那很简单:
var query = from dr in DirectReports
where dr.BonusPlanTemplate != BonusPlanTemplate.Empty
&& !dr.BonusPlans.Any(bp => bp.FiscalPeriod == fiscalPeriod)
select dr;
您可以在Employee
中使用额外的方法让您的生活更轻松:
public bool HasBonusPlanForPeriod(FiscalPeriod period)
{
return BonusPlans.Any(bp => bp.FiscalPeriod == fiscalPeriod);
}
然后您的原始第一个查询变为:
var query = from dr in DirectReports
where dr.BonusPlanTemplate != BonusPlanTemplate.Empty &&
dr.HasBonusPlanForPeriod(fiscalPeriod)
select dr;
IList<Employee> directReportsWithBonusPlansCreated = query.ToList();
,第二个查询变为:
var query = from dr in DirectReports
where dr.BonusPlanTemplate != BonusPlanTemplate.Empty &&
!dr.HasBonusPlanForPeriod(fiscalPeriod)
select dr;
IList<Employee> directReportsWithBonusPlansCreated = query.ToList();
答案 1 :(得分:1)
这是一个棘手的问题......首先我想“哦,这是一个外部联接......使用DefaultIfEmpty”。然后我意识到你正在做一些选择(这是从条款归结为两个)。所以我搜索了与SelectMany和came up with this gem结合使用的DefaultIfEmpty。应用于您的场景我们得到
var query =
from dr in DirectReports
from bp in dr.BonusPlans.DefaultIfEmpty()
where dr.BonusPlanTemplate != BonusPlanTemplate.Empty &&
bp.FiscalPeriod==fiscalPeriod &&
bp==null
select dr;
看看它是否适合你。