2016-07-27 48 views
0

我想創建一個基於我的數據表的參數查詢。我試圖執行類似以下的事情,除非我不斷收到錯誤,並且必須基本重新創建每個case語句中的整個linq查詢,其中一個參數不同。 OrderBy或OrderByDecending。建立LINQ查詢基於關閉參數

有沒有辦法建立基於參數的查詢?

public JsonResult IndexData(DTParameterViewModel param) 
    { 
      IEnumerable<DataTableRowViewModel> rows = (from j in jobs select j) 
         .Skip(param.Start) 
         .Take(param.Length) 
         .AsEnumerable() 
         .Select(j => new DataTableRowViewModel 
         { 
          Id = j.Id, 
          ArrivalDate = j.ArrivalDate.ToString(Constants.DATE_FORMAT), 
          DueDate = j.DueDate?.ToString(Constants.DATE_TIME_FORMAT), 
          Contact = j.Contact, 
          Priority = j.Priority.GetDisplayName(), 
          JobType = j.JobType.GetDisplayName(), 
          SapDate = j.SapDate.ToString() 
         }); 

     foreach(DTOrder order in param.Order) 
     { 
      ascDesc = order.Dir; 

      switch (order.Column) 
      { 
       case 0: 
        orderCol = 0; 
        colName = "Id"; 

        if (ascDesc == "desc") 
        { 
         rows = (from j in jobs select j) 
         .OrderByDescending(j => j.Id); 

        } 
        else 
        { 
         rows = (from j in jobs select j) 
         .OrderBy(j => j.Id) 
        } 

        break; 

       case 1: 
        orderCol = 1; 
        colName = "ArrivalDate"; 

        if (ascDesc == "desc") 
        { 
         rows = (from j in jobs select j) 
         .OrderByDescending(j => j.ArrivalDate) 
        } 
        else 
        { 
         rows = (from j in jobs select j) 
         .OrderBy(j => j.ArrivalDate) 

        } 

        break; 
    } 

回答

1

有這樣做的更復雜的方式,但我覺得這是最簡單的閱讀,尤其是對LINQ初學者:

var first=true; 
foreach(DTOrder order in param.Order) 
{ 
    switch(order.Column) 
    { 
    case 0: 
     if (first) 
     { 
     rows=(order.Dir=="asc")?rows.OrderBy(r=>r.Id):rows.OrderByDescending(r=>r.Id); 
     } else { 
     rows=(order.Dir=="asc")?rows.ThenBy(r=>r.Id):rows.ThenByDescending(r=>r.Id); 
     } 
     break; 
    case 1: 
     ... 
    } 
    first=false; 
} 

通常不過,你會想這樣做你TakeSkip後順序,所以你會做這樣的事情:

public JsonResult IndexData(DTParameterViewModel param) 
{ 
    // Start with the base query 
    var rows = jobs.AsQueryable(); 

    // Order the query 
    var first=true; 
    foreach(DTOrder order in param.Order) 
    { 
    switch(order.Column) 
    { 
     case 0: 
     if (first) 
     { 
      rows=(order.Dir=="asc")?rows.OrderBy(r=>r.Id):rows.OrderByDescending(r=>r.Id); 
     } else { 
      rows=(order.Dir=="asc")?rows.ThenBy(r=>r.Id):rows.ThenByDescending(r=>r.Id); 
     } 
     break; 
     case 1: 
     ... 
    } 
    first=false; 
    } 

    // Partition the query 
    rows=rows 
    .Skip(param.Start) 
    .Take(param.Length) 
    .AsEnumerable(); // Or place the AsEnumerable in the projection 

    // Project the query 
    var result=rows.Select(j => new DataTableRowViewModel 
    { 
     Id = j.Id, 
     ArrivalDate = j.ArrivalDate.ToString(Constants.DATE_FORMAT), 
     DueDate = j.DueDate?.ToString(Constants.DATE_TIME_FORMAT), 
     Contact = j.Contact, 
     Priority = j.Priority.GetDisplayName(), 
     JobType = j.JobType.GetDisplayName(), 
     SapDate = j.SapDate.ToString() 
    }); 

    return result; 
} 

進一步優化(假設就業機會來自數據庫),那麼你應該做一箇中間產物ediate投影限制回來的列,變更:

// Partition the query 
    rows=rows 
    .Skip(param.Start) 
    .Take(param.Length) 
    .AsEnumerable(); // Or place the AsEnumerable in the projection 

    // Project the query 
    var result=rows.Select(j => new DataTableRowViewModel 

這樣:

// Partition the query 
    var result1=rows 
    .Skip(param.Start) 
    .Take(param.Length) 
    /* Selecting only the fields we need */ 
    .Select(j=> new { 
     j.Id, 
     j.ArrivalDate, 
     j.DueDate, 
     j.Contact, 
     j.Priority, 
     j.JobType, 
     j.SapDate 
    }) 
    .AsEnumerable(); // Or place the AsEnumerable in the projection 

    // Project the query 
    var result=result1.Select(j => new DataTableRowViewModel 
+0

這幫助了我這麼多,謝謝你們! – codingNightmares