2012-01-26 68 views
0

我試圖將此SQL轉換爲Linq2SQL查詢,但是,我只是將存儲過程拖到dbml中,希望有人可以做得更好。當沒有嵌套查詢的記錄時,它將返回null。將嵌套總和的sql查詢轉換爲linq2sql

SQL:

SELECT 
    Table1.Field1 - 
    ISNULL(
      (
      SELECT 
       SUM(Table2.Field1) 
      FROM Table2 
       INNER JOIN Table3 ON Table2.ID = Table3.Table2ID 
      WHERE Table3.Table1ID = Table1.ID 
      ) 
      ,0) 
FROM 
    Table1 
WHERE 
    (Table1.ID = @ID) 

LINQ2SQL

 return (from q in db.Table1s 
        where q.ID == id 
        select q.Field1.GetValueOrDefault() - 
          (from o in db.Table2s 
          join r in db.Table3s on o.ID equals r.Table2ID.GetValueOrDefault(0) 
          where r.Table1ID == q.ID 
          select Convert.ToInt32(o.Field1.GetValueOrDefault(0))).Sum() 
        ).SingleOrDefault() 

任何人都可以做的更好。

+0

你爲什麼不滿意你發佈的Linq2SQL?它不是按照要求工作,還是它太複雜/醜陋? – kmote 2012-01-26 22:44:38

+0

對不起,它不起作用。我無法得到正確工作的總和。 – 2012-01-26 22:45:34

回答

2

簡明版的使用方法的語法和lambda表達式:

from t1 in Table1s 
select t1.Field1 - Table3s.Where(x=>x.Table1ID == t1.ID).Sum(y=>y.Table2.Field1) 

更可讀的版本使用的查詢語法使用let聲明:

from t1 in Table1s 
let tmp = 
(
    from t3 in Table3s 
    where t3.Table1ID == t1.ID 
    select t3.Table2.Field1 
).Sum() 
select t1.Field1 - tmp 

我強烈建議使用像LinqPad這樣的工具來設計查詢,因爲它會顯示生成的SQL。這可以讓您調整更昂貴的查詢以獲得更好的結果。

它對快速建立原型和測試短代碼塊也很有用。

+0

+1。我確實使用linqpad,但試圖在匆忙中做到這一點,並無處可去。 – 2012-01-27 13:19:15

1

這可能有所幫助: 我會用另一種方式來制定sql。就像這樣:

SELECT 
    Table1.Field1 - ISNULL(tblTemp.SumOfField1,0) 
FROM 
    Table1 
    LEFT JOIN 
     (
      SELECT 
       SUM(Table2.Field1) AS SumOfField1, 
       Table3.Table1ID 
      FROM Table2 
       INNER JOIN Table3 ON Table2.ID = Table3.Table2ID 
      GROUP BY 
       Table3.Table1ID 
     ) AS tblTemp 
     ON tblTemp.Table1ID = Table1.ID 
WHERE 
    Table1.ID = @ID 

然後你的LINQ代碼可以是這樣的(同樣的結果看它只是另一種方式):

var leftJoin=(
        from Table2 in db.Table2 
        join Table3 in db.Table3 
         on Table2.ID equals Table3.Table2ID 
        group Table3 by Table3.Table1ID into g 
        select new 
        { 
         Table1ID=g.Key, 
         SumOf= g.Sum (x =>x.Field1) 
        } 
       ); 
var output=(
     from Table1 in db.Table1 
     from g in leftJoin 
      .Where (a =>a.Table1ID==Table1.ID).DefaultIfEmpty() 
     select new 
     { 
      Table1.ID, 
      SumOf=(g.SumOf??0)-Table1.Field1 
     } 
    ); 
+0

謝謝,我會給它一個bash。現在有意義把巢拉出來一個單獨的查詢,也使用??。 – 2012-01-27 09:21:53

+0

是的。因爲它將在sql語句中執行。這是因爲左連接是一個IQuerable。如果你對答案很好,那麼你可能會考慮接受答案? – Arion 2012-01-27 09:53:20

+0

Arion,sql很好,但linq需要稍微調整才能工作。我將發佈最終代碼作爲編輯。再次感謝。 – 2012-01-27 09:56:35