【问题标题】:Convert string to Func<T,Object>将字符串转换为 Func<T,Object>
【发布时间】:2015-09-22 17:03:15
【问题描述】:

我有以下方法

     public List<ServicesLogModel> Paging(Func<ServicesLogModel, bool> condition, string columnOrder, bool? orderDescending, int? pageIndex, int? pageSize, out int total)
    {
         return _mongoRepository.Paging(condition, order => order.Message, orderDescending.Value, pageIndex.Value, pageSize.Value, out total);
    }

columnOrder 参数是一个字符串作为 lambda 表达式(例如:order =&gt; order.Message),我必须将其转换为 Func&lt;T, object&gt;

我正在尝试Expression.Parameter

 var parm = Expression.Parameter(typeof(ServicesLogModel), "order");

        var propName = Expression.Property(parm, columnOrder);

        Expression predicateBody = Expression.Assign(parm, propName);


        var test=Expression.Lambda<Func<ServicesLogModel, object>>(predicateBody, parm);

它不起作用 错误:您不能使用“System.String”类型的表达式来分配“ServicesLogModel”类型

编辑:方法签名

public List<T> Paging(Func<T, bool> condition, Func<T, object> order, bool orderDescending, int pageIndex, int pageSize,out int total) 

调用方法

    [HttpGet]
    [Route("Admin/GetReaderConnectorLog/{Apikey}/{SecretKey}/{index}/{pagesize}/{orderAsc}/{columnOrder}")]
    public IActionResult GetReaderConnectorLog(string Apikey, string SecretKey, int? index, int? pagesize, bool? orderAsc, string columnOrder)
    {
        try
        {
            _userService.BeginTransaction();
            //  _webApiHelper.ValidateApiKey(Apikey, SecretKey, Context, _userService, true);
            int total;
            //TEST
            var listModel = _connectorLogService.Paging(_ => true, $"order => order.{columnOrder}", orderAsc, index, pagesize, out total);
            _userService.Commit();
            return _webApiHelper.OkResponse($"{_appSettings.Options.UserTag}[Send List User]", Context, new PaginationModel<ServicesLogModel> { ListData = listModel, Total = total, Apikey = Apikey, SecretKey = SecretKey });
        }
        catch (Exception e)
        {
            _userService.Rollback();
            return _webApiHelper.ResolveException(Context, e);
        }
    }

问候

【问题讨论】:

  • 定义“它不起作用”
  • 仅作记录,当您的返回类型为布尔值时,您可以使用 Predicate 而不是 Func
  • @msmolcic Predicate 早于Func,使用更通用的Func 是完全可以接受的。参见例如 LINQ 的 Where clause public static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;( this IEnumerable&lt;TSource&gt; source, Func&lt;TSource, bool&gt; predicate )。所有 LINQ 都使用Func&lt;T, bool&gt;,并且没有任何地方使用Predicate&lt;T&gt;
  • @ScottChamberlain 实际上他可以更改分页并使用谓词

标签: c# linq lambda expression-trees


【解决方案1】:

嗯,最终的解决方案是这样的

public Func<T, object> GetLambda<T>(string property)
    {
        var param = Expression.Parameter(typeof(T), "p");

        Expression parent = Expression.Property(param, property);

        if (!parent.Type.IsValueType)
        {
            return Expression.Lambda<Func<T, object>>(parent, param).Compile();
        }
        var convert = Expression.Convert(parent, typeof(object));
        return Expression.Lambda<Func<T, object>>(convert, param).Compile();
    }

【讨论】:

  • 您的解决方案在性能方面应该更好,因为它使用表达式来创建比使用反射更快的函数。顺便说一句,我很想知道我提供的解决方案是否有效。
  • 嗨 Yacoub Massad,最后你的解决方案不起作用
【解决方案2】:

由于您的方法需要Func&lt;T,object&gt; 而不是Expression&lt;Func&lt;T,object&gt;&gt;,一个简单的解决方案是使用反射:

public Func<T, object> GetPropertyFunc<T>(string property_name)
{
    return t => typeof (T).GetProperty(property_name).GetMethod.Invoke(t, new object[] {});
}

此方法采用属性名称,并返回所需的函数。

您可以通过以下方式对其进行测试:

ServicesLogModel model = new ServicesLogModel()
{
    Message = "my message"
};

Func<ServicesLogModel, object> func = GetPropertyFunc < ServicesLogModel>("Message"); //I am assuming the property name is "Message", but you can pass any string here

var message = func(model) as string;

【讨论】:

  • 它不起作用,因为不按“消息”属性对列表进行排序......这样工作(_mongoRepository.Paging(条件,p => p.Message,orderDescending.Value,pageIndex。 Value, pageSize.Value, out total) ),但这种方式不是 (return _mongoRepository.Paging(condition, func, orderDescending.Value, pageIndex.Value, pageSize.Value, out total))
  • 您确定您的分页方法接受Func&lt;T, object&gt; order 而不是Expression&lt;Func&lt;T, object&gt; order&gt;
  • yes ..... (public List Paging(Func condition, Func order, bool orderDescending, int pageIndex, int pageSize,out int total )
  • 那么,如果这不起作用,究竟是什么不起作用?它会给你错误的结果吗?还是抛出异常?
  • columnOrder 变量是否等于"Message""order =&gt; order.Message"
猜你喜欢
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多