3

我在 SQL 中有两个表,我将它们填充到 C# 中的 DataTables 中。它们的 SQL 表位于不同的服务器和不同的数据库上。

在第一个表中,我有 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 行,每个拥有 Chat 帐户的用户 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());

        }
4

1 回答 1

5

你想在LEFT JOIN概念上做一个(这是一个OUTER JOIN,而不是一个INNER JOIN)。

表 A 和 B 的左外连接(或简称为左连接)的结果始终包含“左”表 (A) 的所有记录,即使连接条件在“右”表中找不到任何匹配记录(乙)。

来源:http ://en.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在现实世界中确实拥有一个,或者可以真正保证名称都是唯一的并且将始终如一地提供(例如,没有尾随空格或大小写差异)。

// 编辑,解决更新的代码示例

尝试这个:

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)
             };
于 2012-07-24T17:25:29.947 回答