我有一些DB类(EF自动生成)映射到DTO。
我想知道是否有可能从复杂的EF选择查询中映射对象,并使用AutoMapper为单个对象生成的IQueryable ?从我可以看到它只在IQueryable Select链上可用,而不是从lambda内?
我不确定我是否解释得很好,但这是我试图实现的代码
select查询的后半部分无法编译。实体框架类对象(例如a.CRMActivity)不包含'ProjectTo'的扩展方法,因为它是单个对象,而不是可查询的。
--------- MAPPING --------
cfg.CreateMap<Supplier, SupplierDto>().ReverseMap();
cfg.CreateMap<CRMActivity, CrmActivityDto>()
// ignore RTF notes we will generate client side to reduce network traffic (send plaintext version only)
.ReverseMap()
.AfterMap((src, dest) => dest.DetailsRtf = src.ActivityText.PlainTextToRtf());
// etc etc
-------- SELECT QUERY --------
var queryable = repo.DBContext.ProcessItemSupplierOnboardings
.Where(a => a.SupplierCode == supplierCode)
.IncludeOptimized(a => a.CRMActivity)
.IncludeOptimized(a => a.Supplier)
.IncludeOptimized(a => a.ProcessGroup)
.IncludeOptimized(a => a.ProcessItemSteps)
.Select(a => new
{
Activity = a.CRMActivity, // Single object CRMActivity
Supplier = a.Supplier, // Single object Supplier
Group = a.ProcessGroup, // Single object ProcessGroup
Steps = a.ProcessItemSteps // ICollection<ProcessItemStep>
// Want to do this instead (Create an extension Method ProjectTo or use something from AutoMapper existing?)
// This part does not compile because the DB class object does not implement IQueryable.
Activity = a.CRMActivity.ProjectTo<CrmActivityDto>,
Supplier = a.Supplier.ProjectTo<SupplierDto>,
Group = a.ProcessGroup.ProjectTo<ProcessGroupDto>,
Steps = a.ProcessItemSteps.Select(a => a.ProjectTo<ProcessItemStep>)
});
这可能吗?
要利用ProjectTo
,您需要一个顶级DTO:
[Serializable]
public class OnboardingDTO
{
public CrmActivityDto CRMActivity { get; set; }
public SupplierDto Supplier { get; set; }
public ProcessGroupDto ProcessGroup { get; set; }
public ICollection<ProcessItemStepDTO> ProcessItemSteps { get ;set; } = new List<ProcessItemStepDTO>();
}
在你的映射配置中包括:
cfg.CreateMap<ProcessItemSupplierOnboardings, OnBoardingDTO>();
…与其他映射一起。Automapper将在顶级DTO中计算出必要的类型。
现在你的查询表达式:var queryable = repo.DBContext.ProcessItemSupplierOnboardings
.Where(a => a.SupplierCode == supplierCode)
.ProjectTo<OnBoardingDTO>(config);
使用投影时不需要Include
语句。这里假设config
是包含各种DTO配置的MapperConfiguration实例。
一个警告:这个语句可能不会与EF:
一致。.AfterMap((src, dest) => dest.DetailsRtf = src.ActivityText.PlainTextToRtf());
您可能需要将其替换为Ignore
,并确保您的DTO具有适用的原始数据来生成或替换DTO应该显示的内容。