【发布时间】:2014-09-08 12:02:13
【问题描述】:
编辑
为了进一步阐明,在下面的示例中,表达式树是通过使用反射来构建的,以确定相关属性的名称。由于我将“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* 属性在编译时是已知的。如何重构示例以满足我的需求?我认为没有必要 在运行时创建表达式 在运行时评估属性。
【问题讨论】:
-
不太清楚你在问什么。如果您不需要在运行时创建表达式,那么是什么阻止您将表达式编写为普通的 lambda?
-
@SteveRuble 对不起。我澄清了一点。
标签: c# sql linq expression repository-pattern