2012-07-24 29 views
3

我有兩個SQL表,我將它們填充到C#中的DataTable中。他們的SQL表位於不同的服務器和不同的數據庫中。在C#中使用不匹配的數據連接兩個DataTable

在第一個表我有5列

Name(string), AgentStatus(string), TimeInState(double), TaskHandled(double), Region(string) 

第二個表我有3列

Name(string), CChats(double), AChats(double) 

我已使用該鏈路來合併在C#中的表

Inner join of DataTables in C#

但是我遇到的問題是這樣的。

表1有59行,每個用戶1個。

表2有25行,每個用戶有2個聊天帳戶。

當我在C#中合併它們時,我只能從表1中匹配表2中匹配25行的匹配項。我需要顯示錶1中的所有行,並且它們是否在表2中有一行顯示數據,否則顯示0的

我知道那裏的問題是,它在上面的鏈接select語句,但我不知道如何解決它在C#

這裏是我的代碼不能正常工作..... 。列表框只是爲了查看輸出以進行調試.....

 DataTable dt1 = new DataTable(); 
     DataTable dt2 = new DataTable(); 

     dt1.Columns.Add("Name", typeof(string)); 
     dt1.Columns.Add("Status", typeof(string)); 
     dt1.Columns.Add("Time", typeof(double)); 
     dt1.Columns.Add("Calls", typeof(double)); 
     dt1.Columns.Add("Region", typeof(string)); 

     dt2.Columns.Add("Name", typeof(string)); 
     dt2.Columns.Add("CChats", typeof(double)); 
     dt2.Columns.Add("AChats", typeof(double)); 

     foreach(DataRow dr in _agentStates.Rows) 
     { 
      DataRow row = dt1.NewRow(); 
      row["Name"] = dr[0].ToString(); 
      row["Status"] = dr[1].ToString(); 
      row["Time"] = Convert.ToDouble(dr[2].ToString()); 
      row["Calls"] = Convert.ToDouble(dr[3].ToString()); 
      row["Region"] = dr[4].ToString(); 
      dt1.Rows.Add(row); 
     } 
     foreach(DataRow dr in _chatCount.Rows) 
     { 
      DataRow row = dt2.NewRow(); 
      row["Name"] = dr[0].ToString(); 
      row["CChats"] = Convert.ToDouble(dr[1].ToString()); 
      row["AChats"] = Convert.ToDouble(dr[2].ToString()); 
      dt2.Rows.Add(row); 

     } 

     var result = from table1 in dt1.AsEnumerable() 
        join table2 in dt2.AsEnumerable() on (string)table1["Name"] equals (string)table2["Name"] 
        select new 
        { 
         Name = (string)table2["Name"], 
         Status = (string)table1["Status"], 
         Time = (double)table1["Time"], 
         Calls = (double)table1["Calls"], 
         Region = (string)table1["Region"], 
         CChats = (double)table2["CChats"] 
        }; 
     foreach (var item in result) 
     { 
      listBox1.Items.Add(item.Name + " " + item.CChats.ToString()); 

     } 

回答

5

你想要在概念上做一個LEFT JOIN(這是一個OUTER JOIN,而不是一個INNER JOIN)。

左外連接的結果(或只是左連接)爲表A和 乙總是包含了「左」表(A)的所有記錄,即使 加盟條件沒有找到任何(B)中的「正確」表 中的匹配記錄。

來源:http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join

傑夫阿特伍德還張貼的不同加入a decent visual explanation

在LINQ這樣做有點笨拙多比SQL,並且是一樣的東西:

var LeftJoin = from user in Users 
join chat in Chats 
on user.Name equals user.Name into JoinedTables 
from row in JoinedTables.DefaultIfEmpty() 
select new       
{ 
    Name, 
    AgentStatus, 
    TimeInState, 
    TaskHandled, 
    Region, 
    CChats = chat != null ? chat.CChats : 0 
    AChats = chat != null ? chat.AChats : 0       
}; 

來源: http://codingsense.wordpress.com/2009/03/08/left-join-right-join-using-linq/

當然加入了關於Name並不理想 - 希望你確實有或者真的可以保證這些名稱都是唯一的並且將被一致地提供(例如,沒有尾隨空白或大小寫不同)。

//編輯,尋址更新的代碼示例

試試這個:

var result = from table1 in dt1.AsEnumerable() 
      join table2 in dt2.AsEnumerable() 
      on (string)table1["Name"] equals (string)table2["Name"] 
      into joinedDt 
      from table2 in joinedDt.DefaultIfEmpty() 
      select new 
      { 
       Name = (string)table1["Name"], 
       Status = (string)table1["Status"], 
       Time = (double)table1["Time"], 
       Calls = (double)table1["Calls"], 
       Region = (string)table1["Region"], 
       CChats = (table2 != null ? (double)table2["CChats"] : 0) 
      }; 
+0

見我的編輯。仍然卡住,但是你的鏈接很棒! – 2012-07-24 17:45:07

+0

已更新,看看有沒有什麼幫助 – 2012-07-24 17:52:21

+0

當前上下文中不存在'table2'這個名字,並且在CChats行中對table2的引用都有這個名稱。 – 2012-07-24 18:55:48

相關問題