2012-02-24 48 views
6

MVC3,Entity Framework 4.1代碼優先。用於排序導航屬性的動態LINQ表達式

與2個表

模型工作:

public class UniversityMaster 
{ 
    [Key] 
    public string UniversityId { get; set; } 
    public string UniversityName { get; set; } 

} 

public class ProgramMaster 
{ 
    [Key] 
    public string ProgramId { get; set; } 
    public string ProgramName { get; set; } 
    public string UniversityId { get; set; } 
    public virtual UniversityMaster University { get; set; } // navigation property 

} 

用於分揀動態表達(只是爲了避免開關case語句):

public virtual IQueryable<ProgramMaster> GetQueryableSort(string sortField="", string sortDirection="") 
    { 
     IQueryable<ProgramMaster> query = _dbSet; 
     ParameterExpression pe = Expression.Parameter(typeof(ProgramMaster), string.Empty); 
     MemberExpression property = Expression.PropertyOrField(pe, sortField); 
    //get a exception here if the sort field is of navigation property       (University.UniversityName) 
     LambdaExpression lambda = Expression.Lambda(property, pe); 
     if (sortDirection == "ASC") 
     orderbydir = "OrderBy"; 
     else 
     orderbydir = "OrderByDescending"; 
     MethodCallExpression call = Expression.Call(typeof(Queryable), 
     orderbydir, new Type[] { typeof(TEntity), property.Type }, query.Expression, Expression.Quote(lambda)); 

     var returnquery = (IOrderedQueryable<ProgramMaster>)query.Provider.CreateQuery<ProgramMaster>(call); 
     return returnquery; 
    } 

該頁面顯示的網格具有兩個使用webgrid的專欄名稱和大學名稱。對於「程序名稱」列,排序工作正常,但如果按大學名稱排序,則會失敗,因爲此屬性位於UniversityMaster中,並且Expression.PropertyOrField在ProgramMaster中搜索此屬性。這裏是個例外:

University.UniversityName「不是類型的成員」 App.Core.Model.ProgramMaster

我的問題是如何使這項工作對我的模型類的導航性能。

希望我能解釋這種情況。任何幫助表示讚賞。

回答

0

那是因爲MemberExpression正在嘗試調用參數上名爲Univerty.UniversityName的成員。你想要做的是在參數上調用一個名爲Univerity的成員,然後調用UniversityName。實際上,您需要迭代解析屬性名稱。

public virtual IQueryable<ProgramMaster> GetQueryableSort(string sortField = "", string sortDirection = "") 
{ 
    IQueryable<ProgramMaster> query = _dbSet; 

    var propertyNames = sortField.Split("."); 

    ParameterExpression pe = Expression.Parameter(typeof(ProgramMaster), string.Empty); 
    Expression property = pe; 
    foreach(var prop in propertyName) 
    { 
     property = Expression.PropertyOrField(property, prop); 
    } 

    LambdaExpression lambda = Expression.Lambda(property, pe); 

    if (sortDirection == "ASC") 
     orderbydir = "OrderBy"; 
    else 
     orderbydir = "OrderByDescending"; 

    MethodCallExpression call = Expression.Call(
     typeof(Queryable), 
     orderbydir, 
     new Type[] { typeof(TEntity), property.Type }, 
     query.Expression, 
     Expression.Quote(lambda)); 

    var returnquery = (IOrderedQueryable<ProgramMaster>)query.Provider.CreateQuery<ProgramMaster>(call); 

    return returnquery; 
} 
1

Microsoft有一個DynamicQueryable類,它可以用來動態構建使用字符串的LINQ查詢的某些部分。有了這個,你可以說myQuery.OrderBy(「University.UniversityName」),它將處理構建表達式。同一個庫也支持SELECT和WHERE子句的動態構造。

作爲Loresoft出色的EntityFramework.Extended軟件包的一部分,您可以找到源代碼的副本。微軟的檔案號碼是https://github.com/loresoft/EntityFramework.Extended/blob/master/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs