简体   繁体   中英

C# Linq generic search

I am trying to write a method for a base repository service. The idea is I want a generic class that can be used for simple entity types hat can also be overridden for more complex entities. I am writing a search method with the idea being that for simple entities there will be a component which will have one or more properties with fields which match properties of the entity. if these are found then build a where linq statement to query it. Here's what I have so far:

  public IQueryable<T> GetAll()
  {
     return entityRepository.GetAll();
  }

  public IQueryable<T> Search(IBaseComponent component)
  {
     IQueryable<T> all = GetAll();
     Type type = typeof(T);
     Type componentType = component.GetType();

     foreach (var componentProperty in componentType.GetProperties())
      {
        foreach (var property in type.GetProperties())
        {
           if (property.Name.Equals(componentProperty.Name))
           {
              var value = componentProperty.GetValue(component);

              ParameterExpression gpe = Expression.Parameter(property.DeclaringType, "a");
              var selector = Expression.Equal(Expression.Property(gpe, property), Expression.Constant(value));
              var keySelector = Expression.Lambda(selector, gpe);

              var t = all.Where(keySelector);

              break;
           }
        }
      }

     var test = all.ToArray();

     return all;
  }

Obviously this would only theoretically work for one property at the moment. The service itself has a type parameter (so its BaseService<T> ).

The problem I am having is that this will not compile. The line all.Where(keySelector) gives the error:

    'System.Linq.IQueryable<T>' does not contain a definition for 'Where' and the best extension method overload 'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,int,bool>)' has some invalid arguments

I'm not sure what's wrong here, they types are all correct as far as I can see. What am I missing? Or am I trying to do something impossible?

Expression.Lambda return type is LambdaExpression even if the concrete type is Expression<Func<T, bool>> ( LambdaExpression is the non generic base class for Expression<T> )

@Euphoric remark is spot on and the var keyword is the problem here as the reason for this error would have been obvious without it.

The correct code is something like :

var keySelector = (Expression<Func<T, bool>>)Expression.Lambda(selector, gpe);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM