2014-11-25 52 views
0

我有這樣的功能 -.NET動態LINQ的OrderBy加入和嵌套對象

public void ReadTable(string sortField, string sortOrder, string RegID) 
{ 
    sortOrder = sortOrder == "desc" ? "descending" : ""; 

    var db = new MyEntities(); 


    var results = (from CA in db.tblCalifornia 
         join BN in db.tblBeach on CA.BeachID equals BN.BeachID into ps 
         from BN in ps.DefaultIfEmpty() 
        where CA.RegID == regID && CA.tblLife.duration != null 
        orderby sortField + " " + sortOrder 
        select new { CA, BN }).ToList(); 
} 

我想動態排序使用一種名爲tblCalifornia或tblLife的「持續時間」字段中的「城市」字段。我稱之爲ReadTable(「city」,「asc」,「120」)或ReadTable(「CA.city」,「asc」,「120」)的函數。儘管編譯正常並且不會運行時拋出異常,但兩種方法都不起作用。

如何使它工作?

感謝,

回答

1

你混合LINQ到實體W /動態SQL - 這是行不通的。運行時正在從您的linq查詢構建sql查詢,並且它不知道如何將orderby子句中的原始字符串轉換爲動態SQL。

這將讓你接近:

var q = (from CA in db.tblCalifornia 
      join BN in db.tblBeach on CA.BeachID equals BN.BeachhID into ps 
      from BN in ps.DefaultIfEmpty() 
      where CA.RegID == regID && CA.tblLife.duration != null 
      select new { CA, BN } 
     ); 
if (order == "desc") { 
    q = q.OrderByDescending(m => m.CA.city); 
} 
else { 
    q = q.OrderBy(m => m.CA.city); 
} 
var results = q.ToList(); 

排序依據和OrderByDescending是LINQ到實體兼容的方法,所以通過SQL生成的順序正常工作。注意;但是,我明確地將它們使用的表達式設置爲CA.city。 不幸的是我不認爲有可能像EF一樣動態設置你想要的排序。

如果你真的想這樣做 - 檢查出LinqKit http://www.albahari.com/nutshell/linqkit.aspx

其「AsExpandable()」方法將允許您將表達式傳入您的方法,然後您可以編譯並插入到您的linq查詢中。

所以,你的新方法,最終會被稱爲是這樣的:

ReadTable("asc", m => m.CA.City, "120"); 

你必須如下

創建CA和BN明確包含類坐,然後使用表達式
public class Container { 
    public tblCalifornia CA { get; set; } 
    public tblBeach BN { get; set; } 
} 
public void ReadTable(string sortOrder, Expression<Func<Container,string>> fnSortExpr, string regID) { 

    var sort = fnSortExpr.Compile(); 
    var q = (from CA in db.tblCalifornia.AsExpandable() 
      join BN in db.tblBeach on CA.BeachID equals BN.BeachhID into ps 
      from BN in ps.DefaultIfEmpty() 
      where CA.RegID == regID && CA.tblLife.duration != null 
      select new Container { BN = BN, CA = CA } 
     ); 
    if (order == "desc") { 
     q = q.OrderByDescending(sort); 
    } 
    else { 
     q = q.OrderBy(sort); 
    } 
    var results = q.ToList(); 
    ... 
} 

AsExpandable()創建一個IQueryable的包裝器,它允許運行時將表達式轉換爲LINQ-To-Entities可以理解的東西。您首先必須在您的表達式上調用.Compile(),然後在新的可擴展IQueryable中使用它。我假設你的sortBy字段是一個來自瀏覽器的字符串,在這種情況下,你必須在調用此方法之前將支持的字符串映射到表達式。

我還沒有測試過上面的代碼,但希望它能讓你走上正軌。你試圖做的並不是一件容易的事,所以要對自己有耐心。

祝你好運。