2015-09-22 3 views
0

У меня есть следующий методПреобразовать строку Func <T,Object>

 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 является строкой, как лямбда-выражения (например: order => order.Message), что я должен бросить в Func<T, object>

Я пытаюсь с 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

Edit: Method Signature

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); 
     } 
    } 

С уважением

+1

Определение «не работает» – Clint

+1

Просто для записи, вы можете использовать Predicate вместо Func , когда ваш тип возвращаемого значения является логическим. – msmolcic

+2

@msmolcic 'Predicate' predates' Func', вполне приемлемо использовать более универсальный 'Func'. См. Например, предложение LINQ [Where] (https://msdn.microsoft.com/en-us/library/bb534803 (v = vs.100) .aspx) 'public static IEnumerable Где ( \t этот IEnumerable источник , \t Func предикат ) '. Все LINQ использует 'Func ' и нигде не использует 'Predicate '. –

ответ

1

Поскольку ваш метод требуется Func<T,object>, а не Expression<Func<T,object>>, простым решением является использование отражения:

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; 
+0

он не работает, потому что не упорядочивает список по свойству" message "... таким образом работает (_mongoRepository.Paging (условие, p => p.Message, orderDescending.Value, pageIndex.Value , pageSize.Value, out total)), но этим способом нет (return _mongoRepository.Paging (условие, func, orderDescending.Value, pageIndex.Value, pageSize.Value, out total)) – ngonzalezromero

+0

Вы уверены, что ваш метод Paging принимает 'Func order', а не' Expression order> '? –

+0

yes ..... (public List Paging (Func condition, Func order, bool orderDescending, int pageIndex, int pageSize, out int total) – ngonzalezromero

0

Ну, окончательное решение было это

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(); 
    } 
+0

Ваше решение должно быть лучше с точки зрения производительности, поскольку оно использует выражения для создания функции, которая быстрее, чем использование отражения. Кстати, Мне любопытно узнать, работает ли это решение, или нет. –

+0

Hi Yacoub Massad, наконец, ваше решение не работает – ngonzalezromero