關於Linq to Sql 中的left join 中defaultifempty的相關注意事項


在使用Linq to Sql的時候,進行兩個表的左連接的時候要注意defaultifempty的使用,這個函數本來的意思即是:如果為空則使用默認值代替,默認值為 NULL ,當然也可以使用defaultifempty的另一個重載指定默認。如要了解該函數的詳細使用,請看文檔:http://msdn.microsoft.com/zh-cn/library/system.linq.enumerable.defaultifempty.aspx

      看下面的例子:

            var q = (from c in
                         (from a1 in db.StoreIns 
                          group a1 by a1.StoreNum into g 
                          select new { storenum = g.Select(p => p.StoreNum).FirstOrDefault(), total = g.Sum(p =>                                        p.Quantity) })
                     join d in
                         (from a2 in db.StoreOuts
                          group a2 by a2.StoreNum into g2
                          select new { storeNum = g2.Select(p => p.StoreNum).FirstOrDefault(), totalout = g2.Sum(p                          => p.Quantity) }) on c.storenum
                     equals d.storeNum into ord 
                     from t in ord.DefaultIfEmpty()
                     select new 
                     {
                         storeNum = c.storenum,
                         actalIn=c.total,
                         actualOut= (t.totalout==null) ? 0 :t.totalout,
                         actualNum = c.total - ((t.totalout==null) ? 0 :t.totalout)
                     }).ToList();

 

             分解解釋:

             (1)

                   from a1 in db.StoreIns 
                          group a1 by a1.StoreNum into g 
                          select new { storenum = g.Select(p => p.StoreNum).FirstOrDefault(), total = g.Sum(p =>                                        p.Quantity) }

 

                  表示在入庫表中按照庫的編號StorNum進行分組統計每個庫的實際總量,通過匿名類設置了兩個屬性:storenum和total。需要特別注意的是按照分組統計之后,會形成storenum和total的關系是 : 多對一的關系,並且這些storenum是相同的值, 為了后面要進行的左連接,需要取出storenum,此時只能調用FirstOrDefault()函數而不能調用Fisrt(),因為Fisrt()取得是storenum對象,這個對象了存儲的是多個相同的值,在后面得左連接就無法進行。

            (2)

                from a2 in db.StoreOuts
                          group a2 by a2.StoreNum into g2
                          select new { storeNum = g2.Select(p => p.StoreNum).FirstOrDefault(), totalout = g2.Sum(p                          => p.Quantity) }

 

          表示在出庫表中按照庫編號進行分組統計每個庫的實際總量。

 

             (3)

                下面要對上述兩步查詢的到數據進行左連接。

               from c in
                         (from a1 in db.StoreIns 
                          group a1 by a1.StoreNum into g 
                          select new { storenum = g.Select(p => p.StoreNum).FirstOrDefault(), total = g.Sum(p =>                                        p.Quantity) })
                     join d in
                         (from a2 in db.StoreOuts
                          group a2 by a2.StoreNum into g2
                          select new { storeNum = g2.Select(p => p.StoreNum).FirstOrDefault(), totalout = g2.Sum(p                          => p.Quantity) }) on c.storenum
                     equals d.storeNum into ord 
                     from t in ord.DefaultIfEmpty()
                     select new 
                     {
                         storeNum = c.storenum,
                         actalIn=c.total,
                         actualOut= (t.totalout==null) ? 0 :t.totalout,
                         actualNum = c.total - ((t.totalout==null) ? 0 :t.totalout)
                     }

                在上面要注意的是d的訪問范圍,當……into ord……后,只能使用t來訪問數據。如下的訪問方式就是錯誤的:actual=c.total-((d.totalout==null)?0:d.totalout) 就會提示上下文不存在d的錯誤提示。

                這句表示的是使用(1)中數據左連接(2)中的數據。如果(2)中的相關項不存在則使用默認值NULL代替。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM