C# C Linq将表达式转换为类似类的相同属性
我有两个代表实体的类;数据传输类和域类。我有一个方法,它为域类接受一个linq表达式,我想将它转换为数据传输类的同一个linq表达式 阶级策略 { 公共字符串名称{get;set;} } 班级战略 { 公共字符串名称列{get;set;} } 公共异步任务FirstAsyncExpression子句 { //此.source是一个IQueryable。 StrategyDto StrategyDto=wait this.source.FirstAsyncclause;//这里不能使用子句,因为它基于域模型,而不是StrategyDto。如何翻译它? Strategy strategyDomain=strategyDto.ToDomainObject; 返回策略域。 } 示例调用:C# C Linq将表达式转换为类似类的相同属性,c#,linq,C#,Linq,我有两个代表实体的类;数据传输类和域类。我有一个方法,它为域类接受一个linq表达式,我想将它转换为数据传输类的同一个linq表达式 阶级策略 { 公共字符串名称{get;set;} } 班级战略 { 公共字符串名称列{get;set;} } 公共异步任务FirstAsyncExpression子句 { //此.source是一个IQueryable。 StrategyDto StrategyDto=wait this.source.FirstAsyncclause;//这里不能使用子句,因为它
Strategy someStrategy = await queryset.FirstAsync(strat => strat.Name == "Some strategy");
如何将基于域类的子句应用于DTO列表?请注意,这些字段的名称可能略有不同,因为有时类之间会有一些转换。EDIT
你可以用。在应用程序启动中,您需要注册StrategyDto和Strategy之间的映射配置
如果你想接受任何谓词并能够翻译它,那就变得更复杂了。您需要实现ExpressionVisitor,并用新类型替换参数表达式,用正确的属性名称替换属性表达式。您可以找到一个如果您只是要硬编码它,您还可以编写表达式e=strat=>strat.NameColumn==somestrategy。使用这样的代码没有任何用处。也许我不够清楚-通过动态生成表达式,您至少可以更改类型和属性名称,但您不知道要使用的类型或属性名称。请参阅更新。创建自定义属性或将映射元数据存储在字典中并不困难,这样就可以在运行时生成此表达式,但他们的代码中没有这些。这是一种魔术。你需要在某处绘制地图。必须在运行时可探索的映射,以将表达式从传输类转换为域类。也许从这个映射开始,我会重复,也许有可能做点什么。。。但它可能会很复杂,充满局限性。通常,您将使用表达式树,并在两种对象格式之间创建表达式树的转换器。然后,此转换器将使用映射。
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<StrategyDto, Strategy>()
.ForMember(strategy => strategy.Name, options => options.MapFrom(dto => dto.NameColumn));
});
public async Task<Strategy> FirstAsync(Expression<Func<Strategy, bool>> clause)
{
return await this.source
.ProjectTo<Strategy>(config)
.FirstAsync(clause);
}
// The type could be passed in as a parameter or via generics
var dbType = typeof(StrategyDto);
// The property name could be found through reflection
var dbProperty = "NameColumn";
var parameter = Expression.Parameter(dbType, "x");
var property = Expression.Property(parameter, dbProperty);
var value = Expression.Constant("Some strategy");
var equals = Expression.Equal(property, value);
var lambda = Expression.Lambda(equals, parameter);