按多个键查找条目

本文关键字:查找 | 更新日期: 2023-09-27 18:21:07

编辑

为了进一步澄清,在下面的示例中,表达式树是通过使用反射来确定相关属性的名称来构建的。由于我已经将"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*属性在编译时是已知的。如何重构示例以满足我的需求?我认为没有必要在运行时创建表达式在运行时评估属性。

按多个键查找条目

我不确定我是否理解您想要的内容,但如果我做对了,您所需要做的就是在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)
        );
}