У меня есть методы, используемые в IQueryable.Select(...), которые используют ту же логику сопоставления класса Entity с классом DTO, но по-разному фильтруют свойства навигации в проекции. Проблема в том, что существует много разных способов фильтрации дочерних коллекций. Это означает, что все они будут использовать одну и ту же логику сопоставления для сопоставления ParentEntity с ParentDTO. Следовательно, я пытаюсь извлечь эту логику сопоставления.
Причина, по которой я не просто выполнил два отдельных запроса для продуктов и меток, заключается в том, что если есть N продуктов, будет N дополнительных SQL-запросов к меткам (а N может быть большим).
Примечание: .AsExpandable() и .Invoke() взяты из LinqKit Core, так что я могу правильно перевести вложенное выражение с помощью Linq в Sql.) Кроме того, я использую .NET Framework 4.8 с Entity Framework 6.
Ниже приведен код, который у меня есть сейчас (и сгенерированный SQL-запрос выглядит нормально. Никаких проблем с N+1). Есть ли способ извлечь логику сопоставления? (Я готов использовать AutoMapper, если это подойдет.)
/*DAO methods*/
public List ListProductsFilteredByLabelCustomerID
(string productType, string customerID)
{
return context.Product
.AsExpandable()
.Where(product => product.ProductType == productType)
.Select(ToDTOFilteredByLabelCustomerID(customerID));
}
public List ListProductsFilteredByLabelCustomerType
(string productType, string customerType)
{
return context.Product
.AsExpandable()
.Where(product => product.ProductType == productType)
.Select(ToDTOFilteredByLabelCustomerType(customerID));
}
/*Projection Expressions*/
public static Expression
ToDTOFilteredByLabelCustomerID(string customerID)
{
return product => new ProductLabelsDTO {
// I hope to extract these assignments
productName = product.Name,
productDescription = product.Description,
productSKU = product.SKU,
// skipped bunch of other product's fields for simplicity...
//
Labels = product.Labels
.Where(label => label.CustomerID == customerID)
.Select(label => LabelDTO.ToDTO().Invoke(label))
};
}
public static Expression
ToDTOFilteredByLabelCustomerType(string customerType)
{
return product => new ProductLabelsDTO {
// I hope to extract these assignments
productName = product.Name,
productDescription = product.Description,
productSKU = product.SKU,
// skipped bunch of other product's fields for simplicity...
//
Labels = product.Labels
.Where(label => label.CustomerType == customerType)
.Select(label => LabelDTO.ToDTO().Invoke(label))
};
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... llection-f