如何合并对象表达式?

时间:2019-03-31 10:52:18

标签: c# linq lambda

我的问题是如何合并这样的 object 表达式?

Func<T, object>

我在GitHub上创建了a test project,展示了我一直在尝试的内容。

我有一个基本的 boolian 表达式组合,例如here可以正常工作

Expression<Func<Employee, bool>> filter1 = p => p.Name == "John Doe";
Expression<Func<Employee, bool>> filter2 = p => p.Address == "Address 123";

// Two boolean expressions combined
Expression<Func<Employee, bool>> filterCombined = filter1.And(filter2);

// Works as expected
filterCombined.Body.ToString().ShouldBe("((p.Name == \"John Doe\") And (p.Address == \"Address 123\"))");

我无法工作的是将两个 object 对象相结合,例如here

Expression<Func<Employee, object>> filter1 = p => p.Info;
Expression<Func<Employee, object>> filter2 = p => p.Profile;

// Trying to combine two object expressions fails
Expression<Func<Employee, object>> filterCombined = ParameterToMemberExpressionRebinder.CombinePropertySelectorWithPredicate(filter1, filter2);

filterCombined.Body.ToString().ShouldBe("((p => p.Info And p => p.Profile))"); //Something like this anyway...

我尝试了vistor patternLinqKit等各种尝试,但我缺少一些东西。

我要做这一切的主要原因

此问题并非严格需要此信息,但可能会给某人一些额外的见解,而我给他们一些不同的答案。

对于实体框架包含to load related data,我需要这个。但是,在此之上,Automapper无法映射以下内容,因此我试图将所有参数组合起来,然后由Automapper处理。

public MyModelDTO GetById(int? id, params Expression<Func<MyModelDTO , object>>[] includeExpressions)
{
  // here Automapper (with Automapper.Extension.ExpressionMapping) 
  // fails to do the mapping so I´m trying to combine them into one
  Expression<Func<MyModel, object>> mappedExpression= MapToType<Expression<Func<MyModel, object>>>(includeExpressions);

   // call the repository with EF expression
   var myModel = MyRepoGetById(id,mappedExpression);
   ...map myModel back to dto
   return myMappedDtoModel;
}

// The repository method
public MyModel  MyRepoGetById(int id, params Expression<Func<MyModel, object>>[] includeExpressions)
{
        if (includeExpressions.Any())
        {
            IQueryable<T> set = includeExpressions
              .Aggregate<Expression<Func<T, object>>, IQueryable<T>>
                (dbContext.Set<T>(), (current, expression) => current.Include(expression));

            return await set.SingleOrDefaultAsync(s => s.Id == id);
        }

        return dbContext.Set<T>().Find(id);
}
我想这样使用的

var result  = await service.GetById(id,x => x.ClassProperty, x => x.AnotherClassProperty);

0 个答案:

没有答案