3

SQLに2つのテーブルがあり、C#のDataTablesに入力します。これらのSQLテーブルは、さまざまなサーバーとさまざまなDBに格納されています。

最初の表には5つの列があります

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

2番目のテーブルには3つの列があります

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

私はこのリンクを使用してC#のテーブルをマージしています

C#でのDataTablesの内部結合

しかし、私が抱えている問題はこれです。

表1には59行あり、ユーザーごとに1行です。

表2には25行あり、チャットアカウントを持つユーザーごとに2行あります。

それらをC#でマージすると、テーブル2の25行に一致するテーブル1からの一致のみが取得されます。テーブル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)のすべてのレコードが含まれます。 (B)。

ソース: 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 に答える