Create Expression> dynamically and call Aggr

2019-09-16 16:12发布

I'd like to create an Expression<Func<TEntity, object>> so as to later pass it to function as parameter.

If I use the following function for creating it...

public Expression<Func<TEntity, object>> GetInclude(string property)
{
    ParameterExpression parameter = System.Linq.Expressions.Expression.Parameter(typeof(TEntity));
    System.Linq.Expressions.Expression ppty = System.Linq.Expressions.Expression.Property(parameter, property);
    LambdaExpression lambda = System.Linq.Expressions.Expression.Lambda(ppty, parameter);

    return (Expression<Func<TEntity, object>>)lambda;
}

... I get the error at runtime trying to return result, saying that the type cannot be converted into object. For example, if TEntity is Purchases and I want to get Purchases.Customers by giving "Customers" as the parameter.

On the other hand, If I do that function to become generic like...

public Expression<Func<TEntity, TDest>> GetInclude<TDest>(string property) where TDest: class, new()
{
        ParameterExpression parameter = System.Linq.Expressions.Expression.Parameter(typeof(TEntity));
        System.Linq.Expressions.Expression ppty = System.Linq.Expressions.Expression.Property(parameter, property);
        LambdaExpression lambda = System.Linq.Expressions.Expression.Lambda(ppty, parameter);

        return (Expression<Func<TEntity, TDest>>)lambda;
}

... and calling it from Generic Method...

MethodInfo methodInfoInclude = EntityRepository.GetMethod("GetInclude");
object[] parametersToIncludeArray = new object[] { "Customers" };  //For testing

//Get the type of object to be obtained:
Assembly Data = Assembly.Load("Domain.Entities");
Type EntityTypeReferenced = Data.GetTypes()
.Where(t => t.IsClass && t.Namespace == "Domain.Entities" && t.Name == "Customers") //For testing
.ToList<Type>().First();

MethodInfo methodInfoGenericInclude = methodInfoInclude.MakeGenericMethod(EntityTypeReferenced);
object include = methodInfoGenericInclude.Invoke(EntityRepositoryInstance, parametersToIncludeArray);

... I have no error and I can get the include object. However, when I call to method that requires Expression<Func<TEntity, object>> as a parameter:

        object[] Includes = { include };

        MethodInfo methodInfo = EntityRepository.GetMethod("GetElementsWithInclude");
        object[] parametersToIncludeFunctionArray = new object[] { Includes };
        object Data = methodInfo.Invoke(EntityRepositoryInstance, parametersToIncludeFunctionArray);

... with something like...

public List<TEntity> GetElementsWithInclude(Expression<Func<TEntity,object>>[] Includes)
{
    return this.ApplyIncludes(this._Context.CreateDbSet<TEntity>(), Includes).AsEnumerable<TEntity>().ToList();
}

... I get the the error like object[] cannot be converted into Expression<Func<TEntity,object>>[].

The aim is calling function to ApplyIncludes like this, having created the expressions dynamically:

private IQueryable<TEntity> ApplyIncludes(IDbSet<TEntity> Entities, Expression<Func<TEntity, object>>[] Includes)
{
    return Includes.Aggregate(Entities.AsQueryable<TEntity>(),
        (Entity, Include) => Entity.Include(
            ((MemberExpression)Include.Body).Member.DeclaringType.Equals(typeof(TEntity)) ?
            ((MemberExpression)Include.Body).Member.Name :
            Include.Body.ToString().Replace(Include.Parameters[0].Name + ".", "").Replace("FirstOrDefault().", "")
            ));
}

Any help with this, please???

Thank you so much.

0条回答
登录 后发表回答