Я расширил ответ ibrahimozgon, используя динамический тип возврата при выборе определенных столбцов:
public async Task<dynamic> GetDynamicAsync(Expression<Func<T, bool>> where, Expression<Func<T, dynamic>> columns,
params Expression<Func<T, object>>[] navigationProperties)
{
IQueryable<T> query = Context.Set<T>();
query = navigationProperties.Aggregate(query, (current, navigationProperty) => current.Include(navigationProperty));
dynamic entity = await query.Where(where).Select(columns).FirstOrDefaultAsync();
return entity;
}
Это позволит реализовать универсальную реализацию, в которой вы можете отобразить любые поля, требующие сопоставления, с фактическим объектом DTO илианалогичный подкласс:
public class CarMakeDtoConverter : ITypeConverter<object, CarMakeDto>
{
public CarMakeDto Convert(object source, CarMakeDto destination, ResolutionContext context)
=> new CarMakeDto
{
// Because this method's class only takes in object and not dynamic, we need to access the properties via:
// GetType().GetProperty().GetValue()
Id = (int)source.GetType().GetProperty("Id").GetValue(source),
Name = (string)source.GetType().GetProperty("Name").GetValue(source)
};
}
Итак, вы можете использовать следующую реализацию в ваших верхних слоях:
public async Task<CarMakeDto> GetCarMakeDto(int id)
{
var result = await GetDynamicAsync(x => x.Id == id, x => new { x.Id, x.Name});
var carMake = Mapper.Map<CarMakeDto>(result);
return carMake;
}