简化 EF Core 中非集合子属性的 DTO 转换
Entity Framework Core (EF Core) 简化了实体到 DTO(数据传输对象)的转换,特别是对于子集合。 但是,处理单个非集合子属性需要更细致的方法。 将转换逻辑直接嵌入到表达式中虽然有效,但会导致代码重复。
考虑这个例子:
<code class="language-csharp">public static Expression<Func<Model, ModelDto>> AsDto => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModel.AnotherChildModelId } };</code>
为了避免重复代码,利用开源库提供了更优雅的解决方案。 这些库将自定义查询提供程序注入 EF Core,从而能够操作表达式树:
LINQKit: 利用 Expandable
属性和 AsExpandable
扩展方法来修改表达式树。
<code class="language-csharp"> [Expandable(nameof(AsDtoImpl))] public static ModelDto AsDto(Model model) { _asDtoImpl ??= AsDtoImpl().Compile(); return _asDtoImpl(model); } private static Func<Model, ModelDto> _asDtoImpl; private static Expression<Func<Model, ModelDto>> AsDtoImpl => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = ChildModelToDto(model.AnotherChildModel) //Simplified call }; } private static AnotherChildModelDto ChildModelToDto(AnotherChildModel model) { return new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModelId }; }</code>
NeinLinq: 提供 [InjectLambda]
和 ToInjectable()
用于注入自定义 lambda 表达式。 实现方式和LINQKit类似,只是替换了属性和方法。
DelegateDecompiler: 使用 [Computed]
属性进行 lambda 到委托的直接转换。 同样,该结构反映了 LINQKit 示例,为了清晰起见,简化了对单独方法的调用。
通过使用这些库,您可以将子属性转换重构为单独的、可重用的函数,从而显着提高代码的可维护性并减少冗余。 自定义查询提供程序可确保在 EF Core 上下文中正确评估修改后的表达式树。
以上是如何在 EF Core 中高效地将非集合子属性转换为 DTO?的详细内容。更多信息请关注PHP中文网其他相关文章!