Как использовать предложение where для свойства суб-навигации, используя linq и EF
У моей модели есть свойство навигации, а у этого свойства навигации есть другое вспомогательное свойство навигации. Мне нужно использовать where clause
на суб-навигации свойство для фильтрации результатов.
Я пытаюсь использовать запрос linq, но не могу получить результаты
_context.Set<Job>().Include(x=>x.Premises).ThenInclude(y=>y.Station.Where(s=>s.)
Следующий sql join дает мне желаемые результаты
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'
Есть идеи?
1 ответ
Обратите внимание на эти похожие операторы 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();
И то и другое jobs_from_stations
а также jobs
будет содержать точно такие же данные.
Есть разница в фильтрации, хотя.
Если бы вы должны были добавить Where()
предложение в этом запросе, это будет работать по-другому.
Первый запрос будет отфильтрован по объему Job
сущность, тогда как вторая будет фильтровать в рамках Station
юридическое лицо.
Так как вы в настоящее время пытаетесь фильтровать на основе свойства станции, это предлагает использовать второй запрос:
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()
для каждого уровня становится очень громоздким, если вы хотите включить сущности, которые удалены несколько отношений, с которого вы начали.