我正在尝试编写一个过滤父表中字段的查询,包括子表,还过滤子表中的字段。
我通过在子选择器中放置ToList来实现这一点,但这对我来说感觉不对。这是正确的方法吗?
示例:
var query = _context.Set<order_header>()
.Where(oh => oh.customer == accountNo)
.Include(oh => oh.route_details)
.Select(oh => new order_header()
{
customer = oh.customer,
order_no = oh.order_no,
//other columns omitted
route_details = oh.route_details
.Select(rd => new route_detail() { route_code = rd.route_code})
.ToList()//this is odd
});
return query.ToList();
修改: 我已经启用了SQL跟踪,我可以看到这是一个单独的查询来获取每个父行的子代。所以这绝对是做事的错误方式。
我开始认为我必须将结果选择为匿名类型,然后生成EF模型。
EDIT2 : 我现在已经删除了子查询选择中的ToList,但SQL跟踪显示这仍然是为每个父行运行查询。
代码:
var query = _context.Set<order_header>()
.Where(oh => oh.customer == accountNo)
.Include(oh => oh.route_details)
.Select(oh => new
{
customer = oh.customer,
order_no = oh.order_no,
//other columns omitted
route_details = oh.route_details.Select(rd => rd.route_code)
});
var result = query.ToList();
var list = new List<order_header>();
list.AddRange(result.Select(a =>
new order_header()
{
customer = a.customer,
order_no = a.order_no,
//other columns omitted
route_details = a.route_details.Select(rc => new route_detail() { route_code = rc }).ToList()
}));
return list;
EDIT3 根据要求,SQL跟踪:
父查询
exec sp_executesql N'SELECT [oph].[customer], [oph].[order_no], [oph].[customer_order_no], [oph].[date_received], [oph].[date_required], [oph].[date_despatched], [oph].[status], [oph].[to_reference], [oph].[from_reference], [oph].[nett_value]
FROM [scheme].[order_header] AS [oph]
WHERE [oph].[customer] = @__accountNo_0',N'@__accountNo_0 varchar(8)',@__accountNo_0='ACC_NO'
儿童查询
exec sp_executesql N'SELECT [avl].[route_code]
FROM [scheme].[route_detail] AS [avl]
WHERE @_outer_order_no = [avl].[ldordno]',N'@_outer_order_no varchar(10)',@_outer_order_no='1A469499 '
imgur链接 http://i.imgur.com/Q4ATQiU.png
请注意,图片中的架构名称不同,因为我一直在为问题编辑它们。
答案 0 :(得分:0)
您可以使用匿名类型进行选择,然后应该生成一个具有适当联接的查询,类似这样(不确定我的导航属性是否正确):
var query = from oh in _context.Set<order_header>()
where oh.customer == accountNo
select new
{
oh,
oh.route_details,
oh.customer,
// other navigation properties to include
route_details = from rd in oh.route_details
// your child table filtering here
select new
{
rd,
rd.route_code,
// other child nav properties to include
}
};
return query.AsEnumerable().Select(m => m.oh).ToList();