dimanche 3 septembre 2017

c# Expressions - Build nested MemberAccessExpression from PropertyInfo where the Property

I have no idea if I'm even using the correct terms here. I want to build a dynamic search library so that I can build up IQueryables on the fly in code to query a database with. I am decorating certain properties with SearchableAttributes so that I can search the assembly for them using reflection.

I know how to build a MemberAccessExpression from a PropertyInfo - but in this case, the predicate could be n levels deep. It just depends on which Properties are decorated with the SearchableAttribute. For example:

_myDatabaseContext.Set<Entity>().Where(e => e.Name == "Member Access Expression")

_myDatabaseContext.Set<Entity>().Where(e => e.SomeMember.NestedMember.Name == "Member's Member Name")

So, given a PropertyInfo for either Entity.Name OR Entity.SomeMember.SomeMember.Name and the type of Entity how could I build those Expressions up?

Here is the skeleton of the code, ExpressionBuilder.CreateExpression is the method I need to write:

class Program
{
    private SearchableMembersProvider _searchableMembersProvider;

    static void Main(string[] args)
    {
        PropertyInfo[] propertyInfos = _searchableMembersProvider.GetProperties();
        var expressionBuilder = new ExpressionBuilder();
        foreach (var propertyInfo in propertyInfos)
        {
            var expressions = expressionBuilder.CreateExpression<Entity>( propertyInfo );
        }
    }
}

class ExpressionBuilder
{
    public Expression<Func<TEntity, object>> CreateExpression<TEntity>( PropertyInfo propertyInfo )
        where TEntity : EntityBase
    {
        //PropertyInfo here could be eg. x => x.Name *OR* x => x.SomeMember.NestedMember.Name

        //how do I do this..?
    }
}

abstract class EntityBase
{
}

class Entity : EntityBase
{
    [Searchable]
    public string Name { get; set; }

    public SomeMember SomeMember { get; set; }
}

class SomeMember
{
    [Searchable]
    public string Name { get; set; }

    public SomeMember NestedMember { get; set; }
}

class SearchableAttribute : Attribute
{
}





Aucun commentaire:

Enregistrer un commentaire