Я работаю над микросервисами в .Net Core с дизайном, управляемым доменом. Уровень инфраструктуры имеет EF Core DbContext для доступа к базе данных, а в моих репозиториях у меня есть асинхронные методы для извлечения данных.
Поскольку Include/ThenInclude не поддерживает фильтрацию (по крайней мере, до Ef Core 2.1), я перепробовал все возможные подходы, которые нашел, когда искал в Google, как заменить Include. Я также смотрел видео Pluralsight об Ef Core, и когда я увидел опцию Explicit Loading, я был очень счастлив из-за ее способности фильтровать связанные объекты, но когда я переписал один из методов в Explicit версию, запрос, который выполнялся в течение нескольких миллисекунды увеличились до пары минут!
В конфигурациях моих сущностей я настроил все переходы и внешние ключи, но я не уверен, требует ли явная загрузка какой-либо дополнительной настройки или нет? Прежде чем рекомендовать использовать глобальные фильтры, обратите внимание, что предложение Where обычно длиннее, поэтому приведенный ниже пример — это просто укороченная версия реальной фильтрации!
Вот как выглядят мои методы (TransferService служит агрегатом, TransferServiceDetail и любые другие классы — это просто сущности в домене TransferService):
public async Task<IEnumerable<TransferService>> GetAllAsync(
TransferServiceFilter transferServiceFilter)
{
int? pageIndex = null;
int? itemsPerPage = null;
IEnumerable<TransferService> filteredList = DBContext.TransferServices.Where(
ts => !ts.IsDeleted); //This one itself is quick.
//This is just our filtering, it does not affect performance.
if (transferServiceFilter != null)
{
pageIndex = transferServiceFilter.PageIndex;
itemsPerPage = transferServiceFilter.ItemsPerPage;
filteredList = filteredList.Where(f =>
(transferServiceFilter.TransferSupplierId == null ||
f.TransferSupplierId == transferServiceFilter.TransferSupplierId) &&
(transferServiceFilter.TransferDestinationId == null ||
f.TransferDestinationId == transferServiceFilter.TransferDestinationId) &&
(transferServiceFilter.TransferSupplierId == null ||
f.TransferSupplierId == transferServiceFilter.TransferSupplierId) &&
(string.IsNullOrEmpty(transferServiceFilter.TransportHubRef) ||
f.NormalizeReference(f.TransportHubRef) ==
f.NormalizeReference(transferServiceFilter.TransportHubRef)));
}
//This is just for paging and again, this is quick.
return await FilterList(filteredList.AsQueryable(), pageIndex, itemsPerPage);
}
public async Task<IEnumerable<TransferService>> GetAllWithServiceDetailsAsync(
TransferServiceFilter transferServiceFilter)
{
IEnumerable<TransferService> returnList = await GetAllAsync(
transferServiceFilter);
//This might be the problem as I need to iterate through my TransferServices
//to be able to load all TransferServiceDetails that belong to each individual
//Service.
foreach (TransferService service in returnList)
{
await DBContext.Entry<TransferService>(service)
.Collection(ts => ts.TransferServiceDetails.Where(
tsd => !tsd.IsDeleted)).LoadAsync();
}
return returnList;
}
В моем репозитории есть и другие методы, аналогичные предыдущему методу GetAllXY... (у TransferServiceDetails есть Rates, Rates have Periods и т. д.).
Моя идея заключалась в том, чтобы просто вызвать GetAllAsync, когда мне нужны только данные TransferService (и сам по себе этот метод работает молниеносно), или вызвать GetAllWithServiceDetailsAsync, когда мне также нужны сведения о выбранных службах и т. д., но чем ниже я иду в этой иерархии родитель-потомок , тем медленнее становится выполнение, и я говорю о минутах, а не о нескольких дополнительных миллисекундах или, в худшем случае, секундах.
Итак, мой вопрос снова: есть ли какие-либо дополнительные настройки, которые я мог пропустить в конфигурациях объектов, требующих явной загрузки, или просто мои запросы неверны? Или, может быть, явная загрузка хороша только тогда, когда в качестве родителя есть только один TransferService вместо списка TransferServices (50-100 в моем случае), а также есть всего несколько дочерних связанных сущностей (в моем случае у меня обычно есть 5- 10 деталей, каждая деталь имеет 2-3 ставки, каждая ставка имеет ровно 1 период и т.д.)?