问题描述
我想创建一个 Expression< Func< TEntity,object>>
,以便以后将其传递给函数作为参数.
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;
}
...我在运行时遇到错误,试图返回结果,并说无法将类型转换为对象.例如,如果 TEntity
是 Purchases
,而我想通过提供"Customers"
作为参数.
... 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);
...我没有错误,可以获取包含对象.但是,当我调用需要 Expression< Func< TEntity,object>>
作为参数的方法时:
... 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);
...类似...
public List<TEntity> GetElementsWithInclude(Expression<Func<TEntity,object>>[] Includes)
{
return this.ApplyIncludes(this._Context.CreateDbSet<TEntity>(), Includes).AsEnumerable<TEntity>().ToList();
}
...我得到这样的错误,例如 object []
无法转换为 Expression< Func< TEntity,object>> []
.
... I get the the error like object[]
cannot be converted into Expression<Func<TEntity,object>>[]
.
目标是像这样调用函数 ApplyIncludes
并动态创建表达式:
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().", "")
));
}
对此有任何帮助吗?
非常感谢您.
推荐答案
尝试使用此功能,它还会验证要包含的属性是否确实存在.
Try this function, it also validate that the property to include actually exists.
public static Expression<Func<TEntity, object>> BuildIncludeExpression(string include)
{
var entityType = typeof(TEntity);
var propertyInfo = entityType.GetProperty(include);
if (propertyInfo == null)
throw new Exception("Unknown property");
var parameter = Expression.Parameter(entityType);
var property = Expression.Property(parameter, include);
return Expression.Lambda<Func<TEntity, object>>(property, parameter);
}
这篇关于创建表达式< Func< TEntity,object>>.动态地调用Aggregate到IQueryable< TEntity>.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!