带有过滤器的 Linq 一对多
Linq one to many with filter
我有一个要查询的 Entity Framework 数据库,所以我正在使用 linq-to-entities。
这是我的查询:
// 'Find' 只是 returns IQueryable
的包装方法
var q = r.Find(topic =>
topic.PageId != null &&
!topic.Page.IsDeleted &&
topic.Page.IsActive)
// 这些是标准的 EF 扩展方法,用于包括
链接表。 注:Page_Topic与topic是一对多的关系。
.Include(topic => topic.Page.Route)
.Include(topic => topic.Page_Topic.Select(pt => pt.Page.Route))
// 问题来了:这个 select 语句需要展平 Page_Topic
(它确实做到了)。但它似乎在错误的地方这样做。解释一下,如果我要包括另一个依赖于 Page_Topic 的列(例如:'PillarRoutName2',我也必须对该列应用相同的展平逻辑。当然 [=13 的过滤=] 应该以 DRY 方式在更高的查询中完成。
.Select(x => new
{
TopicName = x.Name,
HubRouteName = x.Page.Route.Name,
PillarRouteName = x.Page_Topic.FirstOrDefault(y => y.IsPrimary).Page.Route.Name
}).ToList();
Surely the filtering of Page_Topic should be done higher up the query in a DRY way.
正确!这很容易做到:
.Select(x => new
{
TopicName = x.Name,
HubRouteName = x.Page.Route.Name,
FirstTopic = x.Page_Topic.FirstOrDefault(y => y.IsPrimary)
})
.Select(x => new
{
TopicName = x.TopicName,
HubRouteName = x.HubRouteName,
PillarRouteName = x.FirstTopic.Page.Route.Name,
PillarRoutName2 = x.FirstTopic. ...
}).ToList();
根据您从 FirstTopic
开始获取属性的位置,您还可以在第一部分中使用 x.Page_Topic.FirstOrDefault(y => y.IsPrimary).Page
或 .Page.Route
。
请注意,您不需要 Include
。它们将被忽略,因为查询是一个投影 (Select(x => new ...
)。
我有一个要查询的 Entity Framework 数据库,所以我正在使用 linq-to-entities。
这是我的查询:
// 'Find' 只是 returns IQueryable
的包装方法var q = r.Find(topic =>
topic.PageId != null &&
!topic.Page.IsDeleted &&
topic.Page.IsActive)
// 这些是标准的 EF 扩展方法,用于包括 链接表。 注:Page_Topic与topic是一对多的关系。
.Include(topic => topic.Page.Route)
.Include(topic => topic.Page_Topic.Select(pt => pt.Page.Route))
// 问题来了:这个 select 语句需要展平 Page_Topic
(它确实做到了)。但它似乎在错误的地方这样做。解释一下,如果我要包括另一个依赖于 Page_Topic 的列(例如:'PillarRoutName2',我也必须对该列应用相同的展平逻辑。当然 [=13 的过滤=] 应该以 DRY 方式在更高的查询中完成。
.Select(x => new
{
TopicName = x.Name,
HubRouteName = x.Page.Route.Name,
PillarRouteName = x.Page_Topic.FirstOrDefault(y => y.IsPrimary).Page.Route.Name
}).ToList();
Surely the filtering of Page_Topic should be done higher up the query in a DRY way.
正确!这很容易做到:
.Select(x => new
{
TopicName = x.Name,
HubRouteName = x.Page.Route.Name,
FirstTopic = x.Page_Topic.FirstOrDefault(y => y.IsPrimary)
})
.Select(x => new
{
TopicName = x.TopicName,
HubRouteName = x.HubRouteName,
PillarRouteName = x.FirstTopic.Page.Route.Name,
PillarRoutName2 = x.FirstTopic. ...
}).ToList();
根据您从 FirstTopic
开始获取属性的位置,您还可以在第一部分中使用 x.Page_Topic.FirstOrDefault(y => y.IsPrimary).Page
或 .Page.Route
。
请注意,您不需要 Include
。它们将被忽略,因为查询是一个投影 (Select(x => new ...
)。