2017-03-09 117 views
0

我有一些會計應用程序,它允許創建文檔併爲其添加一些位置(行/行)。 這裏的控制器來獲得特定文檔的那些行:結合不同的查詢

public JsonResult GetIncDocDetails(long id, int pagesize, int pagenum) 
    { 
     var dbResult = db.fooIncDocDetail.Where(d => d.DocumentID == id).Where(d => d.RecordStatusID != 2).Include(f => f.fooFood). 
          OrderBy(d => d.Date). 
          Select(s => new 
          { 
           s.IncDocDetailID, 
           s.FoodID, 
           s.MeasureUnit, 
           s.Amount, 
           s.Price, 
           s.VATRate,   
           s.Excise, 
           s.DocumentID, 
           s.UserID, 
           s.RecordDate,    
           s.RecordStatusID, 
           s.Date, 
           s.FoodName, 
           s.DetailNumber, 
           fooFoodName = s.fooFood.Name 
          }).Skip(pagesize * pagenum).Take(pagesize); 

     return Json(dbResult, JsonRequestBehavior.AllowGet); 
    } 

所以,我想通過這個控制器,如一些更多的信息:

  1. 這個特殊的文件中的所有行的總和:

    Summa = db.fooIncDocDetail.Where(d => d.DocumentID == id). 
            Where(d => d.RecordStatusID == 1). 
            Sum(a => (decimal?)(a.Amount* a.Price)) ?? 0; 
    
  2. 這個特殊的文件中的所有行的總計數:

    這個特殊的文件
    Total = db.fooIncDocDetail.Where(d => d.DocumentID == id). 
            Where(d => d.RecordStatusID != 2) 
            .Count() 
    
  3. 屬性:

    Document = db.fooDocument.Where(d => d.DocumentID == id). 
                 Select(d => new 
                 { 
                  d.DocumentID, 
                  d.DocDate, 
                  d.RegNumber, 
                  d.UserID, 
                  d.RecordDate, 
                  d.RecordStatusID, 
                  d.RegistrationDate, 
                  d.Number, 
                  d.Description, 
                  d.ObjectID, 
                  d.DocumentTypeID, 
                  d.ContragentName, 
                  DocumentTypeName = d.fooDocumentType.Name 
                 }) 
    

但我怎麼能結合所有,在短短一個LINQ查詢,這是我寫的第一?謝謝

+0

我不會嘗試將所有這些查詢合併成一個,而不是我想創建一個數據庫中的參數化存儲過程,並使用它。這可能會創造最少的開銷,因爲您只需發送一個查詢並獲得所有答案。 – Robert

+0

「fooDocument」和「fooInDocDetail」不相關嗎?它們之間不應該有關係,所以你可以用'.Include()'加載所有相關的實體?既然你想要所有的細節,那麼在數據庫中執行聚合就不會使* all *有多大意義。一旦你在客戶端上有數據,你就可以執行你想要的任何類型的聚合。 –

回答

1

基本上,您可以將所有的細節查詢嵌入到最後一個查詢Select中,方法是將它們投影到匿名或特定創建類型的屬性中,以便原始(1)和(2)變爲(3)的子查詢。只要改變d變量來避免衝突,例如:

// The original query. Must be declared here and put into variable 
// to avoid exception due to `Skip`/`Take` subquery processing EF bug 
// It still will be executed as part of the other query 
var details = ...; 

var result = db.fooDocument 
    .Where(d => d.DocumentID == id). 
    .Select(doc => new 
    { 
     Document = new 
     { 
      doc.DocumentID, 
      doc.DocDate, 
      doc.RegNumber, 
      doc.UserID, 
      doc.RecordDate, 
      doc.RecordStatusID, 
      doc.RegistrationDate, 
      doc.Number, 
      doc.Description, 
      doc.ObjectID, 
      doc.DocumentTypeID, 
      doc.ContragentName, 
      DocumentTypeName = doc.fooDocumentType.Name 
     }, 
     Summa = ..., 
     Total = ..., 
     Details = details 
    }) 
    .FirstOrDefault(); 
+0

謝謝,伊萬,請檢查: –

+0

//請求詳細信息= 詳細信息= doc.fooIncDocDetail.Where(f => f.RecordStatusID!= 2)。 OrderBy(f => f.Date)。 選擇(詳細=>新的 { //一些明細屬性 })。 跳過(pagesize * pagenum).Take(pagesize) 我得到了這個異常:Count必須是DbConstantExpression或DbParameterReferenceExpression –

+0

然後沒有其他選擇,而不是使'Details'部分分開。我有一些關於將它與其他部分相結合的抱怨,因爲即使它起作用,它也會創建一個很大的聯合查詢,其中有許多字段在主數據庫中未使用,許多字段在返回的單個結果集的詳細記錄中未使用。所以,排除來自答案的詳細信息並執行2個查詢,我認爲它仍然優於4 :) –