在LINQ中附加到Func
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在LINQ中附加到Func相关的知识,希望对你有一定的参考价值。
我有一个投影方法
public IQueryable<EmpDTO> GetEmployee(Func<Employee, EmpDTO> projection = null)
{
if(projection == null)
projection = emp => new EmpDTO {
Id = emp.Id,
Name = emp.Name,
Salary = emp.Salary,
};
return entities.Employees.Where(e => e.Salary > 10000).Select(projection);
}
它可以扩展如下:
query = classInstance.GetEmployee(emp => new EmpDTO {
Id = emp.Id,
Name = emp.Name,
Salary = emp.Salary,
Address = emp.Address
});
如何在不重写整个字段的情况下仅将“地址”字段附加到Func(重复字段Id,Name,Salary)
答案
使用Expression
,您可以构建一个新的lambda来初始化字段:
public IQueryable<EmpDTO> GetEmployee(Expression<Func<Employee, EmpDTO>> addProj = null) {
Expression<Func<Employee, EmpDTO>> projection = emp => new EmpDTO {
Id = emp.Id,
Name = emp.Name,
Salary = emp.Salary,
};
if (addProj != null) {
var pBody = ((MemberInitExpression)projection.Body);
var newBindings = new ReadOnlyCollection<MemberBinding>(pBody.Bindings.Concat(((MemberInitExpression)addProj.Body).Bindings).ToList());
var newBody = Expression.MemberInit(pBody.NewExpression, newBindings);
projection = (Expression<Func<Employee, EmpDTO>>) Expression.Lambda(newBody, projection.Parameters);
}
return entities.Employees.Where(e => e.Salary > 10000).Select(projection);
}
你也可以从头开始构建整个lambda,但这对我来说似乎更有用。另外,您可以将combine init逻辑封装到扩展方法中:
public static Expression<Func<TIn, TOut>> Add<TIn, TOut>(this Expression<Func<TIn, TOut>> proj, Expression<Func<TIn, TOut>> addProj = null) {
if (addProj != null) {
var pBody = ((MemberInitExpression)proj.Body);
var newBindings = new ReadOnlyCollection<MemberBinding>(pBody.Bindings.Concat(((MemberInitExpression)addProj.Body).Bindings).ToList());
var newBody = Expression.MemberInit(pBody.NewExpression, newBindings);
proj = (Expression<Func<TIn, TOut>>)Expression.Lambda(newBody, proj.Parameters);
}
return proj;
}
这将GetEmployee
身体减少到:
public IQueryable<EmpDTO> GetEmployee(Expression<Func<Employee, EmpDTO>> addProj = null) {
Expression<Func<Employee, EmpDTO>> projection = emp => new EmpDTO {
Id = emp.Id,
Name = emp.Name,
Salary = emp.Salary,
};
if (addProj != null)
projection = projection.Add(addProj);
return entities.Employees.Where(e => e.Salary > 10000).Select(projection);
}
以上是关于在LINQ中附加到Func的主要内容,如果未能解决你的问题,请参考以下文章