如何将Func<DepartmentViewModel, bool>
转换为
Func<Department, bool>
?
我看过很多关于这个问题的帖子,但没有一个可以帮助我。
我称之为此功能:
public DepartmentViewModel GetSingle(Expression<Func<DepartmentViewModel, bool>> whereCondition)
来自GUI层,如下所示:
_departmentService.GetSingle(de => de.Id ==id));
和位于我的业务层的GetSingle
内部函数我必须调用
public IEnumerable<Department> GetAll(Func<Department, bool> predicate = null)
但GetAll
函数接受Func<Department, bool>
类型
这是我的目标:
class Department {
public string name
}
和
class DepartmentViewModel{
public string name
}
方面,我找到了最佳答案:
Func<DepartmentViewModel, bool> some_function = whereCondition.Compile();
Func<Department, bool> converted = d => some_function(
new DepartmentViewModel {
Id=d.Id,
Description=d.Descriptions
}
);
答案 0 :(得分:1)
您无法将Func<T1,bool>
更改为Func<T2,bool>
,但您可以转换相同的表达式。
这需要一些工作,首先你必须传递Expression<Func<T,bool>>
,然后你可以轻松转换表达式以匹配传入的参数。
所以你可以改变你的方法,
Expression<Func<DepartmentViewModel,bool>> srcLambda =
x => x.DepartmentName.StartsWith("Admin")
Expression<Func<Department,bool>> destLambda =
ConvertTo<Department,DepartmentViewModel>( srcLambda);
这假设DepartmentViewModel(DTO)与Department具有相同的字段。否则,您必须稍微更改代码以满足您的需求。
public static Expression<Func<TDest,bool>>
ConvertTo<TSrc,TDest>(Expression<Func<TSrc,bool>> srcExp)
{
ParameterExpression destPE = Expression.Parameter(typeof(TDest));
ExpressionConverter ec = new ExpressionConverter(typeof(TSrc),destPE);
Expression body = ec.Visit(srcExp.Body);
return Expression.Lambda<Func<TDest,bool>>(body,destPE);
}
public class ExpressionConverter: ExpressionVisitor{
private Type srcType;
private ParameterExpression destParameter;
public ExpressionConverter(Type src, ParameterExpression dest){
this.srcType = src;
this.destParameter= dest;
}
protected override Expression
VisitParameter(ParameterExpression node)
{
if(node.Type == srcType)
return this.destParameter;
return base.VisitParameter(node);
}
}
答案 1 :(得分:0)
我假设您需要向Entity Framework(或其他一些查询提供程序)发出这些查询。在这种情况下,您需要使用表达式而不仅仅是函数,因为只有前者存储了提供者需要转换的查询信息(例如,存储到SQL查询中)。
这是一个简单的例子:
Expression<Func<DepartmentViewModel, bool>> filterDVM = dvm => dvm.Name == "abc";
您首先需要一些接受Department
并将其转换为DepartmentViewModel
的逻辑:
Expression<Func<Department, DepartmentViewModel>> getViewModel = dep =>
new DepartmentViewModel
{
Name = dep.Name,
Location = dep.Location,
};
完成此操作后,您可以将转换应用到IQueryable<Department>
序列,之后,您可以应用过滤器:
var dvm = context.Departments.Select(getViewModel).Where(filterDVM);