修改
为了进一步说明,在下面的示例中,通过使用反射来构建表达式树,以确定相关属性的名称。因为我有" T"定义为类泛型并已限制在某个接口,我正在寻找强类型方法。这应该是IMO。
期望的结果 伪
public class RepositoryBase<TEntity, TKey> : IRepository<TEntity, TKey>
where TEntity : IEntity<TKey>
{
protected virtual ISpecification<TEntity> ByMultipleKeysSpecification(IEnumerable<TKey> keys)
{
return keys.Select(key =>
Expression.Lambda<Func<TEntity, bool>>(entity => key.Equals(entity.Id)))
.Aggregate<Expression<Func<TEntity, bool>>, ISpecification<TEntity>>(null,
(current, lambda) => current == null ? new ExpressionSpecification<TEntity>(lambda) : current.Or(lambda)
);
}
}
我正在寻找一种方法来创建一个通过多个键查找实体的规范。我已经在网上找到了这个例子:
keys.Select(key =>
Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.PropertyOrField(parameter, propInfo.Name),
Expression.Constant(key)
), parameter
)
)
.Aggregate<Expression<Func<T, bool>>, ISpecification<T>>(null,
(current, lambda) => current == null ? new Specification<T>(lambda) : current.Or(lambda)
);
这个示例接近我的需要,但是它在运行时使用反射来评估 id 属性的名称,因为任何类型都可以用作 T 。在我的例子中,我将可能的类型限制为自定义接口( IEntity ),因此* id *属性在编译时是已知的。我如何重构示例以满足我的需求?我不认为有必要在运行时创建表达式在运行时评估属性。
答案 0 :(得分:1)
我不确定我理解你在寻找什么,但如果我说得对,你需要做的就是在Select
电话中将你的表达式转换为正确的类型。这将告诉编译器在编译时将其视为表达式,因此您不需要在运行时构建它。
protected virtual ISpecification<TEntity> ByMultipleKeysSpecification(IEnumerable<TKey> keys)
{
return keys.Select(key => (Expression<Func<TEntity, bool>>)(entity => key.Equals(entity.Id)))
.Aggregate<Expression<Func<TEntity, bool>>, ISpecification<TEntity>>(null,
(current, lambda) => current == null ? new Specification<TEntity>(lambda) : current.Or(lambda)
);
}