2014-09-08 2 views
0

EditLookup записей по нескольким клавишам

Для дальнейшего уточнения, в приведенном ниже примере, выражение дерево будет построено с помощью отражения, чтобы определить имя соответствующего свойства. Поскольку у меня есть «Т», определенный как общий класс и уже ограничен определенным интерфейсом, я ищу строго типизированный подход. Это должно быть возможным ИМО.

Желаемый результатпсевдо

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) 
      ); 

Этот пример приходит близко к тому, что мне нужно, однако он оценивает имя идентификатора собственности во время выполнения с помощью отражения, так как любой тип может быть использован в качестве T , В моем случае я ограничил возможные типы для пользовательского интерфейса (IEntity), поэтому свойство * id * известно во время компиляции. Как я могу реорганизовать этот пример в соответствии с моими потребностями? Я не думаю, что необходимо создать выражение во время выполнения оценить свойство во время выполнения.

+1

Это не совсем понятно, о чем вы просите. Если вам не нужно создавать выражение во время выполнения, что мешает вам просто написать выражение как нормальную лямбду? –

+0

@SteveRuble Извините. Я немного объяснил это. – xvdiff

ответ

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) 
     ); 
} 
+0

Это именно то, что я искал! – xvdiff

Смежные вопросы