C# 如何使用linq和EF在子导航属性上使用where子句

C# 如何使用linq和EF在子导航属性上使用where子句,c#,linq,C#,Linq,我的模型有一个导航属性,此导航属性有另一个子导航属性。我需要在子导航属性上使用where子句,以筛选结果 我正在尝试使用linq查询,但无法获得结果 \u context.Set().Include(x=>x.Premises)。然后Include(y=>y.Station.Where(s=>s.) 下面的sql联接为我提供了所需的结果 select * from [dbo].[JOB] J inner join [dbo].[PREMISES] P on J.Premis

我的模型有一个导航属性,此导航属性有另一个子导航属性。我需要在子导航属性上使用
where子句
,以筛选结果

我正在尝试使用linq查询,但无法获得结果

\u context.Set().Include(x=>x.Premises)。然后Include(y=>y.Station.Where(s=>s.)

下面的sql联接为我提供了所需的结果

select * 
  from [dbo].[JOB] J inner join 
       [dbo].[PREMISES] P on J.PremisesId = P.Id inner join 
       [dbo].[STATION] S on P.StationCode=S.StationCode
 where S.StationCode = '001'

有什么想法吗?

请注意这些类似的LINQ声明:

var jobs = db.Jobs
                .Include(j => j.Premises)
                .Include(j => j.Premises.Select(p => p.Stations))
                .ToList();

var stations = db.Stations
                .Include(s => s.Premise)
                .Include(s => s.Premise.Job)
                .ToList();
虽然您的返回类型不同,但实际上您在内存中保存了相同的数据。我也可以使用第二个来获取所有作业:

var jobs_from_stations = stations.Select(s => s.Premise.Job).Distinct();
来自站点的
作业和
作业将包含完全相同的数据

但在过滤方面存在差异。

如果要在此查询中添加
Where()
子句,则其工作方式会有所不同

第一个查询将在
作业
实体的范围内进行过滤,而第二个查询将在
站点
实体的范围内进行过滤。
由于您当前正在尝试基于桩号特性进行筛选,因此建议使用第二个查询:

var stations = db.Stations
                .Include(s => s.Premise)
                .Include(s => s.Premise.Job)
                .Where(s => s.StationCode == "001")
                .ToList();
如果希望返回类型为作业列表:

var jobs = db.Stations
                .Include(s => s.Premise)
                .Include(s => s.Premise.Job)
                .Where(s => s.StationCode == "001")
                .Select(s => s.Premise.Job)
                .Distinct()
                .ToList();
请注意,仍然可以使用第一个查询,但它会变得更加冗长和笨拙:

var jobs = db.Jobs
                .Include(j => j.Premises)
                .Include(j => j.Premises.Select(p => p.Stations))
                .Where(j => j.Premises.Any(p => p.Stations.Any(s => s.StationCode == "001")))
                .ToList();

根据经验,我总是尝试从孩子开始,然后一步一步往上。正如您在上面的示例中所看到的,这使筛选更容易。但您可能也注意到,它使
Include()
语句保持简单:

.Include(s => s.Premise)
.Include(s => s.Premise.Job)
而不是

.Include(j => j.Premises)
.Include(j => j.Premises.Select(p => p.Stations))

虽然这两个示例在功能上是等效的,但如果要包含从开始位置删除的多个关系的实体,则必须为每个级别添加一个
Select()
,这将非常麻烦。

请显示导航属性。这些属性是否为集合?