我在SQL中有两个表,这些表已填充到C#中的DataTables中。它们的SQL表位于不同的服务器和不同的DB上。
在第一个表中,我有5列
Name(string), AgentStatus(string), TimeInState(double), TaskHandled(double), Region(string)
第二张表我有3列
Name(string), CChats(double), AChats(double)
我一直在使用此链接合并C#中的表
C#中的DataTables的内部联接
但是我遇到的问题是这个。
表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()); }
您要在LEFT JOIN概念上进行操作(这是OUTER JOIN,而不是INNER JOIN)。
LEFT JOIN
OUTER JOIN
INNER JOIN
表A和B的左外部联接(或简称为左联接)的结果始终包含“左”表(A)的所有记录,即使联接条件未在“右”表中找到任何匹配的记录(B)。 来源:http://zh.wikipedia.org/wiki/Join_(SQL)#Left_outer_join
表A和B的左外部联接(或简称为左联接)的结果始终包含“左”表(A)的所有记录,即使联接条件未在“右”表中找到任何匹配的记录(B)。
来源:http://zh.wikipedia.org/wiki/Join_(SQL)#Left_outer_join
杰夫·阿特伍德(Jeff Atwood)也对不同的连接发表了不错的视觉解释。
在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并不是理想的选择- 希望您实际上ID在现实世界中拥有一个,或者真的可以保证名称都是唯一的并且将被一致地提供(例如,没有尾随空格或大小写差异)。
Name
ID
//编辑,处理更新的代码示例
试试这个:
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) };