Linq中join & group join & left join 的用法

Linq中join & group join & left join 的用法

 分類:

文章轉自:http://www.cnblogs.com/c-jquery-linq-sql-net-problem/archive/2011/01/17/LINQ_Inner_Join_Group_Join_Left_Join.htmlhtml

咱們在作SQL查詢的時候常常會用到Inner Join,Left Join,笛卡爾積等等,鏈接方式的概念方面我想也不用給予太多解釋,jquery

咱們今天的重點是讓你們熟悉LINQ是如何使用Join來實現經常使用的錶鏈接的。sql

建立測試用類:數組

[csharp]  view plain  copy
 
  1. class Customer  
  2. {  
  3.     public int CustomerId { get; set; }  
  4.   
  5.     public string Name { get; set; }  
  6.   
  7.     public int Age { get; set; }  
  8.   
  9. }  
  10.   
  11. class Product  
  12. {  
  13.     public int ProductId { get; set; }  
  14.   
  15.     public string Name { get; set; }  
  16.   
  17.     public string Origin { get; set; }  
  18.   
  19. }  
  20.   
  21. class Order  
  22. {  
  23.     public int OrderId { get; set; }  
  24.   
  25.     public int CustomerId { get; set; }  
  26.   
  27.     public List<Product> Products { get; set; }  
  28. }  

咱們用如下例子來熟悉 Join 關鍵字的用法。函數

1.Inner Join:post

[csharp]  view plain  copy
 
  1. CreateEntities();  
  2. var query = from c in customers  
  3.             join o in orders on c.CustomerId equals o.CustomerId  
  4.             where o.OrderId == 2  
  5.             select c;  
  6. foreach (var customer in query)  
  7. {  
  8.     Console.WriteLine("Id:{0}, Name:{1}", customer.CustomerId, customer.Name);  
  9. }  

 

運行結果:測試

  Id:1, Name:CA   ui

 上面這個是常見的內鏈接的例子,和SQL語法也很類似,但有如下幾點要注意:google

(1).鏈接條件: c.CustomerId equals o.CustomerId 只能使用 equals 不能用 =,==,等於 等表示。
覺得LINQ的設計者認爲 幾乎全部的鏈接條件都是 = 條件不會出現 >,<,!= 等狀況所以使用了個關鍵字來描述錶鏈接條件。url

(2).條件順序:c.CustomerId equals o.CustomerId ,range variable: c 和b以前的順序不能顛倒。

 

2.Group Join:

也許你們對Group Join的概念不太瞭解,不要緊讓咱們經過例子來認識它:

[csharp]  view plain  copy
 
  1. CreateEntities();  
  2. var query = from c in customers  
  3.             join o in orders on c.CustomerId equals o.CustomerId into os  
  4.             select new { c, os };  
  5. foreach (var item in query)  
  6. {  
  7.     Console.WriteLine("Customer Id:{0}, Name:{1}", item.c.CustomerId, item.c.Name);  
  8.     foreach (var o in item.os)  
  9.     {  
  10.         Console.WriteLine("--Order Id:{0}", o.OrderId);  
  11.     }  
  12. }  

結果:

Customer Id:1, Name:CA
--Order Id:1
--Order Id:2
Customer Id:2, Name:CB
--Order Id:4
Customer Id:3, Name:CC
--Order Id:3
Customer Id:4, Name:CD
Press any key to continue . . .

以上查詢返回的結果:和Group By 返回的結果很是的類似:一個KEY對象對應一個集合。

要實現Group Join咱們要引入一個關鍵字:into

但使用時要注意一下幾點:

(1).使用into 關鍵字後 join 後面的 range variable:o 在後面的表達式塊中就失去了做用域。

(2).range variable:os 一般狀況下都是IEnumerable<T>類型的。

 

3.Left Join:

 Left Join 咱們在SQL裏常常用到,讓咱們來看看LINQ裏怎麼實現它:

[csharp]  view plain  copy
 
  1. CreateEntities();  
  2. var query = from c in customers  
  3.             join o in orders on c.CustomerId equals o.CustomerId into os  
  4.             from o2 in os.DefaultIfEmpty(  
  5.                 new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })  
  6.             select new { c, o2 };  
  7. foreach (var item in query)  
  8. {  
  9.     Console.WriteLine("Customer Id:{0}, Name:{1}--Order Id:{0}",  
  10.         item.c.CustomerId, item.o2.OrderId);  
  11. }  

結果:

Customer Id:1, Name:1--Order Id:1
Customer Id:1, Name:2--Order Id:1
Customer Id:2, Name:4--Order Id:2
Customer Id:3, Name:3--Order Id:3
Customer Id:4, Name:0--Order Id:4
Press any key to continue . . . 

咱們能夠看到Left Outer Join 的語法進一步的複雜化了,結果也有細微的不一樣。

(1).從語法上:

from o2 in os.DefaultIfEmpty(
                new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })

主要區別在於以上者1句語句。查詢方法DefaultIfEmpty 用於定義當查詢記錄爲空時,預約義默認值。再從其集合中取出子元素。

(2).從結果上: 咱們在遍歷查詢結果時能夠發現Left Join類似於Inner Join結果都是「平面」的,然而Group Join返回的結果具備層次性。

 

題外:

因爲C#是面向對象的,每每會經過對象與對象間的外系來實現數據間關係。有時表達2個之間的關係也能夠不使用Join關鍵字,

所以Join關鍵字其實在實際LINQ查詢表達式中用的不是不少。

 

 

# Linq獲取兩個List或數組的差集交集

 
複製代碼
List<int> list1 = new List<int>();
list1.Add(1);
list1.Add(2);
list1.Add(3);
List<int> list2 = new List<int>();
list2.Add(3);
list2.Add(4);
list2.Add(5);
//獲得的結果是4,5 即減去了相同的元素。
List<int> list3 = list2.Except(list1).ToList();
foreach (int i in list3)
{
    MessageBox.Show(i.ToString());
}
複製代碼
合併兩個數組,並去掉重複元素,而後排序(C#)
複製代碼
List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 12, 10 };
List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
var newQuerty = numbers1.Concat(
from n in numbers2
where !numbers1.Contains(n)
select n
).OrderBy(n=>n);
複製代碼
合併兩個數組,並去除合併後的重複數據, 並排序

            int[] A={1,2,2,3,4,5,6,6,6};
            int[] B={2,2,2,3,7,8,9,5};

            List<int> list = new List<int>(A);
            list.AddRange(B);

            list.Sort();

            //去除重複項
            foreach (int i in list.Distinct<int>())
            {
                Console.WriteLine(i);
            }

C# 取兩個數組的相同元素

以往咱們都是確定絞盡腦汁,確定什麼循環,元素大小,什麼因素都考慮進去。可是如今採用Linq能夠很好的解決這個問題。找出兩個或多個數組的相同項。

代碼至關簡單:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Text;

 

namespaceTest4_03

{

   classProgram

    {

       staticvoidMain(string[] args)

        {

           string[] names = {"Adams","Arthur","Buchanan","Tsbuchis","ShCian","FuchsiaLinda","DecheChen","Lotheer","FindLanciCade","SorchLand","JiangZheng","MisiiLoda","Gtod","Dfac","Lama","BakCades","Losangle","ZheWQ","GehengDahaLothi","ToryLandey","DakaLothy","BthLanda","MenNorth","Fith","FoxMain","DontM","Saobba","Del","Sala","Ghero","BhthLaPhda"};

           IEnumerable<string> skip = names.Skip(10);

           IEnumerable<string> take = names.Take(11);

 

           //取出兩個序列中交集部分,按理論應該輸出JiangZheng

           IEnumerable<string> intersect = skip.Intersect(take);

 

           foreach(varsinintersect)

            {

               Console.WriteLine(s);

            }

           Console.ReadKey();

        }

    }

}

 

C# 獲取兩個數組集合的差集,交集

今天在作一個樹形選擇節點時,遇到一個問題,屬性節點是記錄了相關的ID值,第一次呢所有對這些ID進行處理,可是接下來再次選擇就要分狀況了,原先選擇的ID若是不在新選擇的集合中那麼剔除掉,不然,原先ID不傳入函數處理,新ID傳入函數處理:

好比原來①選擇的ID是:1,2,3,4                下次:1,2,3,4,5,   那麼這時候5要處理,1,2,3,4維持原樣。

              ②選擇ID是:1,3                          下次: 3,4,5           那麼這時候4,5 要處理,3 維持原樣。1剔除。

              ③選擇ID是:1,2,3,4,5                  下次:3,4,5             那麼這時候3,4,5都維持原樣,1,2剔除。

              ④選擇ID是:1,2                           下次:3,4,5             那麼這時候3,4,5處理,1,2剔除。

 

簡化一下數學模型:

你們發現沒其實這就是一個數學的概念,集合的差集,那麼咱們怎麼處理呢? 假設前次選擇的集合爲A,後次選擇爲B

獲得要處理的很簡單:B-A (B與A的差集)就是要處理的集合元素,爲何呢?根據概念可知哈!

那麼獲得不作處理的怎麼辦呢? 不要處理的必然是B的子集,那麼怎麼獲得呢?

出來啦既是:B-(B-A)    這是爲何呢? B-A  就是要處理的,而維持原樣的就是固然就是:B-(B-A),

那麼剔除的集合呢? A-(B-(B-A)) 

 

如何用C#表示呢,我這裏就不用什麼循環之類的了,我用的是NET3.5 那就好辦了,用Linq處理:

俺這裏特殊點,右鍵獲得的樹形集合(lstSource)包含了其餘信息,先獲取ID集合再說:

 var m_ilAllSelect = lstSource.Select(r => r.ID).AsEnumerable();//新選擇的列表

///////下面開始處理了

List<int> m_ilNewSelect = m_ilAllSelect.ToList();//新選擇列表
List<int> m_ilExcept = m_ilNewSelect.Except(m_mcuids).ToList(); //二者的不一樣之處
List<int> m_iExceptAfterAndNew = m_ilNewSelect.Except(m_ilExcept).ToList();//新選擇列表與差集比較,則是新選擇中的舊的

 

爲了簡化給你們,這裏的A表明舊集合,B表明新集合,這裏的集合都是List<int>泛型列表。

那麼要處理的就是 B.Except(A), 維持原樣的:B( B.Except(A)), 剔除的:A.Except(B( B.Except(A))),

不要問我這個Except方法啥意思?看MSDN吧,google也行啦!

固然我實際的源碼比這更細緻點,至此解決集合的差集的知識點就這些了!

相關文章
相關標籤/搜索