[英]EF Core header-detail query optimization
I have a header-detail relation in my SQL Server database.我的 SQL Server 数据库中有一个 header-detail 关系。 I have around 10k headers, each of them having 1-1k details.
我有大约 10k 个标题,每个标题都有 1-1k 个详细信息。 And the number of unique elements is about 1k.
并且唯一元素的数量大约为 1k。
Elements [id]
1
2
3
Headers [id]
1
2
3
Details [id, header_id, element_id]
1 1 1
2 1 2
3 1 3
4 2 1
5 3 1
It's very easy to query a list of headers with their details with such structure:使用这种结构查询带有详细信息的标题列表非常容易:
var searchHeaderIds = new List<int>{1,2,3};
var headers = context.Headers
.Where(h => searchHeaderIds.Contains(h.Id))
.Include(h => h.Details)
.ToList();
But what I want to query is a list of elements (1-200) where every element has a list of headers it belongs to (something like an inversion).但是我要查询的是一个元素列表(1-200),其中每个元素都有一个它所属的标题列表(类似于倒置)。 I can write it in C# as below:
我可以用 C# 编写它,如下所示:
var searchElementIds = new List<int>{1,2,3};
var headers = context.Details
.Where(d => searchElementIds.Contains(d.element_id))
.GroupBy(d => d.element_id)
.Select(g => new {
id = g.Key,
header_ids = g.Select(x => x.header_id) })
.ToList();
But I wonder, what will be the fastest way to do it using the power of SQL/EF?但我想知道,使用 SQL/EF 的强大功能最快的方法是什么?
UPD: I'm ready to use extra data structures, preprocess the data in the database, or do anything else to improve performance. UPD:我准备好使用额外的数据结构,预处理数据库中的数据,或者做任何其他事情来提高性能。
what about:关于什么:
var searchElementIds = new List<int>{1,2,3};
var headers = (
from header in context.Headers
join detail in context.Details on header.id equals detail.header_id
where searchElementIds.Contains(detail.element_id)
select header).Distinct();
If you want instances of the Element
class:如果你想要
Element
类的实例:
var headers =
context.Details
.Where(d => searchElementIds.Contains(d.element_id))
.GroupBy(d => d.element_id)
.Select(g => new Element
{
id = g.Key,
header_ids = g.Select(x => x.header_id
})
.ToList();
Don't cal ToList()
in the middle of your query.不要在查询中间调用
ToList()
。
This is most optimal query in your case.在您的情况下,这是最佳查询。 It is closer to original post, but reduced number of retrieved fields for intermediate result:
它更接近原始帖子,但减少了中间结果的检索字段数量:
var headers = context.Details
.Where(d => searchElementIds.Contains(d.element_id))
.Select(d => new { d.element_id, d.header_id })
.ToList() // we need this, EF do not support retrieving grouping detals
.GroupBy(d => d.element_id)
.Select(g => new Element
{
id = g.Key,
header_ids = g.Select(x => x.header_id).ToList()
})
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.