Create generic selector for Select() while using Entity Framework

Viewed 665

I would like to create a function to retrieve a List of a given property name's Type. But i dont know yet how to create a working lambda selector.

public IList<object> GetDistinctListOfProperty(string propertyName)
{
    var propInfoByName = typeof(T).GetProperty(propertyName);
    if (propInfoByName == null) return new List<object>();

    using (var db = new ApplicationDbContext())
    {
        var lambda = //TODO
        return db.Set<T>().Select(lambda).Distinct().ToList();
    }
}
2 Answers

You can use this method to generate lambda

public static Expression<Func<T, object>> LambdaGenerator<T>(string propertyName)
    {
        var arg = Expression.Parameter(typeof(T), "current");
        var property = Expression.Property(arg, propertyName);
        var conv = Expression.Convert(property, typeof(object));
        var exp = Expression.Lambda<Func<T, object>>(conv, new ParameterExpression[] { arg });
        return exp;
    }

and then use this method to create your expression

var lambda = LambdaGenerator<T>("Your Property Name");

You can use an expression for this:

private IList<Tout> GetDistinctListOfProperty<Ttable, Tout>(Expression<Func<Ttable, Tout>> returnField) where Ttable : class
{
    using (var db = new ApplicationDbContext())
    {
        return db.Set<Ttable>().Select(returnField).Distinct().ToList();
    }
}

You need to wrap the Func into an Expression so that entity can translate it into a valid sql. This version allows you to use intellisense when you choose your parameter. You would call it like this:

var result = GetDistinctListOfProperty<YourTableType>(x => x.YourProperty);

This version will work on every table that is known to your ApplicationDbContext

Related