Search code examples
c#linqlambdapetapoco

How do I get property names of a type using a lambda expression and anonymous type?


I am trying to use Expression Trees and anonymous types to achieve the following.

Let's say I have this class:

class Person
{
   public string FirstName {get;set;}
   public string MiddleName {get;set;}
   public string LastName {get;set;}
   public DateTime DateOfBirth {get;set;}
}

Now I want to be able to call the following:

string[] names = Foo<Person>(x=> new { x.LastName, x.DateOfBirth });

I want names to contain 2 items, "LastName" and "DateOfBirth".

I am trying to extend PetaPoco, in a compile time safe way rather than writing string sql, so that I can specify a list of properties/columns I want to include in the SQL, rather than it selecting everything. I have some pretty large entities and there are cases where I do not want to select all the columns for performance reasons.


Solution

  • I'm lazy so this code handles only public properties. But it should be a good base to get you started.

    public static string[] Foo<T>(Expression<Func<T, object>> func)
    {
        var properties = func.Body.Type.GetProperties();
    
        return typeof(T).GetProperties()
            .Where(p => properties.Any(x => p.Name == x.Name))
            .Select(p =>
            {
                var attr = (ColumnAttribute) p.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
                return (attr != null ? attr.Name : p.Name);
            }).ToArray();
    }