结合使用AutoMapper Mapping和EF Select Query



我有一些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应该显示的内容。

最新更新