0

I would like to do pass the filter as string parameter.

public static List<Contact> Search(string filtre){
   var contacts =  bdContext.Contact.OrderBy( e => e.[filtre]).ToList();
   return contacts;
}

Code:

var contacts = bdContext.Contact.OrderBy(e.GetType().GetProperty(filter))
Nico
  • 12,493
  • 5
  • 42
  • 62

3 Answers3

0

If you want to pass filter as a parameter and get the list then you need to do this:

public static List<Contact> Search(string filtre){
   var contacts =  bdContext.Contact.where( e => e.columnname.Contains(filtre)).OrderBy(x=>x.ColumnName).ToList();
   return contacts;
}
rohit singh
  • 550
  • 1
  • 11
  • 32
0

You can use https://www.nuget.org/packages/System.Linq.Dynamic.Library or https://www.nuget.org/packages/System.Linq.Dynamic/ (they are are library to execute "dynamic" queries based on string commands. They are nearly equivalent, because one is a branch of the other).

using System.Linq.Dynamic;

and then

var contacts = bdContext.Contact.OrderBy(filtre).ToList();

Now... if you don't really want to include a new library, you can do something like:

// We build the expression x => x.[filtre]
var parameter = Expression.Parameter(typeof(Contact));
var property = Expression.Property(parameter, filtre);
var expression = Expression.Lambda(property, parameter); // Returns a Expression<Func<Contact, typeof(propertyName)>>

// The "right" overload of OrderBy, in a "safe" way
var orderby = (from x in typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public)
               where x.Name == "OrderBy" && x.IsGenericMethod
               let genericArguments = x.GetGenericArguments()
               let parameters = x.GetParameters()
               where genericArguments.Length == 2 && 
                   parameters.Length == 2 &&
                   parameters[0].ParameterType == typeof(IQueryable<>).MakeGenericType(genericArguments[0]) &&
                   parameters[1].ParameterType == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(genericArguments))
               select x).Single();

// We build from OrderBy<,> the OrderBy<Contact, typeof(filtre)>
orderby = orderby.MakeGenericMethod(typeof(Contact), expression.ReturnType);

// We invoke OrderBy<Contact, typeof(filtre)>
IQueryable<Contact> ordered = (IQueryable<Contact>)orderby.Invoke(null, new object[] { bdContext.Contact, expression });
var contacts = ordered.ToList();
xanatos
  • 109,618
  • 12
  • 197
  • 280
0

You can use Dynamic Linq which is available on Nuget. You'll need to add the namespace System.Linq.Dynamic then you'll be able to pass a string to the OrderBy function.

using System.Linq.Dynamic;
...
public static List<Contact> SearchDynamic(string filtre)
{
    var contacts = Contacts.OrderBy(filtre).ToList();
    return contacts;
}
...
Contacts = SearchDynamic("SomeProperty");

Alternatively, you could pass an Expression<Func<Contact, T>> to your search method. This sounds more complicated than it is:

//no need for Dynamic Linq here
public static List<Contact> Search<T>(Expression<Func<Contact, T>> filtre)
{
    var contacts = Contacts.OrderBy(filtre).ToList();
    return contacts;
}
...
Contacts = Search(c => c.SomeProperty);
petelids
  • 12,305
  • 3
  • 47
  • 57
  • Considering he is using a variable with name `bdContext.Contact`, I'll say he is using Entity Framework/LINQ2SQL. So the second example would be better as `Expression>` – xanatos Apr 10 '15 at 12:21
  • 1
    Thanks @xanatos, I've updated the answer as I assume you're right (although the question isn't tagged as such). I note you have a `Cast` on your answer - is this required with EF as in my test using objects it's not required. – petelids Apr 10 '15 at 12:26
  • Sorry i should tell that I am using entity framework – Fabrice Kyams Apr 10 '15 at 12:46