首页 > 解决方案 > 如何使用动态生成的 LINQ 表达式动态调用需要 LINQ 表达式的方法?

问题描述

我有一堆通过子父关系与其他人相关的实体。所有这些实体都有一个引用其父级的属性,但其名称因实体而异。我有一个方法,Query用签名调用:

public virtual IQueryFluent<TEntity> Query(Expression<Func<TEntity, bool>> query)

该方法位于与每个实例对应的每个存储库(存储库模式)中。这是我们从数据库中恢复实例的方式。

我希望能够通过其父 Id 属性的值恢复一组具有某些指定父级的实体。假设我有一个这样调用的方法:

masterTableService.GetParented("ChildEntityService", "ParentPropId", someParentIdValue);

所以我创建了这两种方法:

public MasterTableDto GetParented(string serviceName, string descriptionField, string parentField, int? parentId, string idField = ID_PROPNAME)
{
    var service = ResolveService(serviceName);
    var entityType = GetMethodAllReturnType(service);

    var parentProp = entityType.GetProperty(parentField);
    var parentPropType = parentProp.GetMethod.ReturnType;

    var x = Expression.Parameter(entityType, "x");
    var parentPropExpression = Expression.PropertyOrField(x, parentField);
    var parentIdExpression = Expression.Constant(parentId);
    var parentIdSameTypeExpression = Expression.Convert(parentIdExpression, parentPropType);
    var body = Expression.Equal(parentPropExpression, parentIdSameTypeExpression);
    var lambda = Expression.Lambda(body, x);

    var parameters = new object[] { lambda };

    try
    {
        var foo = CallMethod(service, "Query", parameters);

        // More stuff...

        return dto;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

public object CallMethod(object service, string methodName, object[] parameters)
{
    var serviceType = service.GetType();

    var method = serviceType.GetMethods().Where(mf => mf.GetParameters().Count() == 1).First();
    var result = method.Invoke(service, parameters); // Error :'(

    return result;
}

一切正常,直到我到达标有“错误”的行。我得到一个例外:

Cannot convert 'System.Linq.Expressions.Expression`1[System.Func`2[Entities.SqlServer.RCE.Tramo,System.Boolean]]' to type 'System.Object[]'.

事实上,该Query方法永远不会被调用。

我究竟做错了什么?

标签: c#linqlinq-expressions

解决方案


推荐阅读