Я пытаюсь объединить таблицы продуктов и атрибутов и сгруппировать их по идентификатору продукта, чтобы получить список продуктов с их атрибутами.Поэтому я попробовал следующий запрос Entity Framework:
var productsWithAttributes = (from product in ctx.products
join attribute in ctx.attributes on product.id equals attribute.productId
select new
{
product = product,
a1 = attribute.a1,
a2 = attribute.a2,
a3 = attribute.a3,
a4 = attribute.a4
} into t
group t by t.product.id into g
select new
{
product = g.Select(p => p.product).FirstOrDefault(),
attributes = g.Select(r => new Attr()
{
a1 = r.a1,
a2 = r.a2,
a3 = r.a3,
a4 = r.a4
}).ToList()
}
).ToList();
Но это заняло около 70 минут, и когда я посмотрел на полученный SQL-запрос, я увидел десятки подзапросов с десятками объединений.
Затем я попытался выполнить группировку на сервере sql и сделал проекцию на нужную структуру на сервере приложений.И это код EF для этого:
var productsWithAttributes = (from product in ctx.products
join attribute in ctx.attributes on product.id equals attribute.productId
select new
{
product = product,
a1 = attribute.a1,
a2 = attribute.a2,
a3 = attribute.a3,
a4 = attribute.a4
} into t
group t by t.product.id
).ToList();
Это заняло около 3 минут.Но SQL, созданный этим запросом, все еще выглядит сложным с несколькими подзапросами и объединениями.Я хотел бы увидеть что-то вроде:
select product.*, attribute.a1, attribute.a2, attribute.a3, attribute.a4
from product
join attribute on product.id = attribute.productId
group by product.id
Затем я попытался просто объединить без группировки:
var productsWithAttributes = (from product in ctx.products
join attribute in ctx.attributes on product.id equals attribute.productId
select new
{
product = product,
a1 = attribute.a1,
a2 = attribute.a2,
a3 = attribute.a3,
a4 = attribute.a4,
}
).ToList();
Это заняло 1,5 минуты, и код SQL, созданный EF, был, как ожидалось.
Короче говоря, добавление группировки в объединение создает сложный SQL-запрос, который занимает больше времени, но все еще приемлем с точки зрения производительности.Но добавление окончательного прогноза после этой группировки приводит к невероятно запутанному SQL-запросу, который занимает недопустимое количество времени.
Как правильно создать этот запрос с EF?