2013-07-31 207 views
6

我有說在這裏問類似的問題: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expressionLINQ到實體無法識別方法「方法名稱」方法

我想我的分頁源,但對我來說,我可以「T放GetPropertyValue結果在一個變量,因爲我需要x做到這一點:

public IEnumerable<TModel> Paginate(IQueryable<TModel> source, ref int totalPages, int pageIndex, int pageSize, string sortfield, SortDirection? sortdir) 
{ 
    totalPages = (int)Math.Ceiling(source.Count()/(double)pageSize); 

    if (sortdir == SortDirection.Descending) 
    { 
     return source.OrderByDescending(x => GetPropertyValue(x, sortfield)).Skip(pageIndex * pageSize).Take(pageSize).ToList(); 
    } 
    else 
    { 
     return source.OrderBy(x => GetPropertyValue(x, sortfield)).Skip(pageIndex * pageSize).Take(pageSize).ToList(); 
    } 
} 

private static object GetPropertyValue(object obj, string name) 
{ 
    return obj == null ? null : obj.GetType().GetProperty(name).GetValue(obj, null); 
} 

我能做什麼,在這種情況下?

+0

什麼樣的問題到底在哪裏?它看起來好像你得到一個不是所有的路徑返回一個值? – Sayse

+0

我得到一個「LINQ to Entities不能識別方法'方法名'的方法」,更具體地說是「GetPropertyValue」方法。 –

回答

6

Lambda表達式(那些在Where,OrderBy等中使用)不能包含任何特定於C#的代碼,它們只能包含表達式樹,並將其轉換爲SQL。除了那些由EF文檔提到的方法,例如SqlFunctions等,您不能調用任何方法。

爲了在運行時使用字段名進行排序,您必須在運行時創建lambda表達式並將其傳遞給它上。

public IEnumerable<TModel> Paginate(IQueryable<TModel> source, ref int totalPages, int pageIndex, int pageSize, string sortfield, SortDirection? sortdir) 
{ 
    totalPages = (int)Math.Ceiling(source.Count()/(double)pageSize); 

    if (sortdir == SortDirection.Descending) 
    { 
     return source.OrderByDescending(sortfield).Skip(pageIndex * pageSize).Take(pageSize).ToList(); 
    } 
    else 
    { 
     return source.OrderBy(sortfield).Skip(pageIndex * pageSize).Take(pageSize).ToList(); 
    } 
} 


public static class QueryableHelper 
{ 
    public static IQueryable<TModel> OrderBy<TModel>(this IQueryable<TModel> q, string name) 
    { 
     Type entityType = typeof(TModel); 
     PropertyInfo p = entityType.GetProperty(name); 
     MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByProperty").MakeGenericMethod(entityType, p.PropertyType); 
     return(IQueryable<TModel>) m.Invoke(null, new object[] { q, p }); 
    } 

    public static IQueryable<TModel> OrderByDescending<TModel>(this IQueryable<TModel> q, string name) 
    { 
     Type entityType = typeof(TModel); 
     PropertyInfo p = entityType.GetProperty(name); 
     MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByPropertyDescending").MakeGenericMethod(entityType, p.PropertyType); 
     return (IQueryable<TModel>)m.Invoke(null, new object[] { q, p }); 
    } 

    public static IQueryable<TModel> OrderByPropertyDescending<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p) 
    { 
     ParameterExpression pe = Expression.Parameter(typeof(TModel)); 
     Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object)); 
     return q.OrderByDescending(Expression.Lambda<Func<TModel, TRet>>(se, pe)); 
    } 

    public static IQueryable<TModel> OrderByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p) 
    { 
     ParameterExpression pe = Expression.Parameter(typeof(TModel)); 
     Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object)); 
     return q.OrderBy(Expression.Lambda<Func<TModel, TRet>>(se, pe)); 
    } 
} 

此解決方案只適用於財產單級,但如果你想嵌套級別比它需要更多的工作,也許你可以看看下面的SDK這確實這一切。

但是,如果你看看Entity REST SDK本身,它有許多事情和所有你可能需要的東西。免責聲明:我是作者。

https://entityrestsdk.codeplex.com

+0

幾乎工作。現在我得到一個「System.Int64」類型的表達式不能用於返回類型'System.Object'「。 我改變了'Func >'爲'Func >',它工作,但我不知道將傳遞給函數的對象的類型。例如,可以是'String'。無論如何解決這個問題? –

+2

你現在可以試試嗎?我修改了一點。如果它運作良好,我將離開家,否則我會嘗試發佈解決方案,即稍大一些,但那將是明天。 –

+0

我沒有,但非常感謝你的幫助 –

1

而不是使用反射,您應該動態創建一個Expression<Func<TSource, TOrder>>並將其傳遞到OrderBy

看看here瞭解如何創建動態查詢。

相關問題