1

Я загружаю ServiceTrips для календаря планирования и задаюсь вопросом, существует ли самый быстрый подход для активной загрузки связанных данных из многих таблиц.Eager Loading Complex Query with Entity Framework 5

Вот модель, которая должна быть загружена (отображение в таблице для каждого типа бетона)

public class ServiceTrip : BaseEntity 
{ 
    public ICollection<Employee> Crew { get; set; } 
    public ICollection<ServiceAssignment> Assignments { get; set; } 
} 

public class ServiceAssignment : BaseEntity 
{ 
    public ServiceOrder ServiceOrder { get; set; } 
    public DeliveryOrder DeliveryOrder { get; set; } 
} 

public class ServiceOrder : OrderBase { } 
public class DeliveryOrder : OrderBase { } 

public abstract class OrderBase : BaseEntity 
{ 
    public ICollection<ServiceAssignment> Assignments { get; set; } 
    public Sale Sale { get; set; } 
} 

public class Sale : BaseEntity 
{ 
    public Employee Manager { get; set; } 
    public Customer Customer { get; set; } 
    public ICollection<ServiceOrder> ServiceOrders { get; set; } 
    public ICollection<DeliveryOrder> DeliveryOrders { get; set; } 
} 

public class Employee : BaseEntity { } 
public class Customer : BaseEntity { } 

public abstract class BaseEntity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

Я в основном пытался что-то вроде этого и не знаю с чего начать.

var tripsQuery = db.ServiceTrips 

.Where(x => x.StartDate >= FirstDay && x.StartDate <= LastDay) 

.Include(x => x.Crew) 
.Include(x => x.ServiceAssignments) 

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder)) 
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder)) 

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale)) 
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale)) 

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale.Customer)) 
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale.Customer)) 

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale.Manager)) 
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale.Manager)) 
; 

Модель упрощена. В производстве я занимаюсь примерно 20 столами. Загрузка занимает около 10-15 секунд. Я пробовал загружать каждый день асинхронно, но увеличил общее время загрузки.

+1

Производительность зависит от множества факторов, размера набора результатов, если у вас есть индексы на столбцах, которые вы сканируете и т. Д. Моя рекомендация состояла бы в том, чтобы воспроизвести то, что вы пытаетесь сделать в сыром SQL, и это даст вам представление о том, является ли ваш запрос в настоящее время необоснованным. –

+1

Поскольку ни одна из коллекций не является «виртуальной», я бы утверждал, что данные загружаются без какого-либо из «Include» – qujck

+0

@qujck ah yes that that right. Это ошибка, которую я сделал при упрощении модели для вопроса. Они являются виртуальными в моей модели производства, но я явно отключил ленивую загрузку. – Benjamin

ответ

1

На моем взгляде, когда вы выдавшие сложный запрос, который соединяет через двадцать таблиц вы можете захотеть начало с проверкой самой базы данных

Вот некоторые рекомендации (некоторые пункты имеют отношение к SQL Server, который я имею взял на себя смелость предположить, является базой данных вы используете)

  1. Проверьте план выполнения запроса на необработанного SQL - Если это занимает много времени, чтобы воспроизвести весь код EF в SQL только возможно его части - например, таблицы ServiceTrips, ServiceAssignments и DeliveryOrder. Это даст вам представление о том, узких местах в отношении индексов и т.д.

  2. инспектировать, если из-за размером данных, задержки в сети является узким местом, а не запрос самого

  3. Рассмотрите возможность использования indexed views, которые могли бы повысить производительность

  4. Архитектура - для ускорения таких сложных запросов используют кэширование какой-то, возможно, хранить соответствующие данные - в вашем случае, может быть, имена менеджеров, экипажа и т.д.

+0

Спасибо. Это оказалось комбинацией нескольких вещей. – Benjamin