我的目标是以可缩放的方式处理到DTO的某些映射,以减少某些样板。我必须在这里使用Iqueryable,并且不能只调用.toList()。
这件作品。 (还要注意,示例中显示了BusinessUnit的所有属性,尽管我还有大约25个要映射的对象-有些很大)
//class BusinessUnitController
private IQueryable<BusinessUnitDTO> BuildProjections()
{
IQueryable<BusinessUnitDTO> results = DataContext.BusinessUnits
.AsNoTracking()
.Select(BusinessUnitMapper.EntityToMessage);
return results;
}
//Class businessUnitMapper
public static Expression<Func<BusinessUnit, BusinessUnitDTO>> EntityToMessage = from => new BusinessUnitDTO
{
Id = from.Id,
Name = from.Name,
Code = from.Code
};
不幸的是,当我还需要能够在其他用例中调用它时,这并不能真正实现如此大的扩展。所以我也有以下几分。
public BusinessUnitDTO Map(BusinessUnit from)
{
BusinessUnitDTO result = null;
if (from != null)
{
result = new BusinessUnitDTO
{
Id = from.Id,
Name = from.Name,
Code = from.Code
};
}
return result;
}
和
public static BusinessUnitDTO MapToMessage(this BusinessUnit businessUnit)
{
BusinessUnitMapper mapper = new BusinessUnitMapper();
return mapper.Map(businessUnit);
}
在两种情况下都必须有一种方法可以重用此映射。我试图直接调用该扩展名。示例:
.Select(BusinessUnit.MapToMessage());但是,这不能工作,因为它无法将其转换为SQL。
那么我该如何为这两个功能用例提供服务,同时仍然只需要构建一次映射?我有什么办法可以使用泛型在这里大大减少样板?
答案 0 :(得分:1)
编译供客户端使用的映射器:
#class BusinessUnitMapper
public static Func<BusinessUnit, BusinessUnitDTO> BU2DTO = EntityToMessage.Compile();
public BusinessUnitDTO Map(BusinessUnit from)
{
BusinessUnitDTO result = null;
if (from != null)
{
result = BU2DTO(from);
}
return result;
}
我无法抗拒一线:
public BusinessUnitDTO Map(BusinessUnit from) => from != null ? BU2DTO(from) : default;