【问题标题】:join 2 datarow rows into one row C#将 2 个数据行行合并为一行 C#
【发布时间】:2013-06-01 11:40:10
【问题描述】:

虽然我知道我可以通过 sql 连接 2 行,但我的程序不使用它 我有 2 个数据表,我取每一行,与另一个表上的行进行比较,并希望从中进行连接

 public DataTable joinTables (DataTable t1, DataTable t2)
    {
        DataTable joinTable = new DataTable();
        foreach (DataRow r1 in t1.Rows)
        {
            foreach (DataRow r2 in t2.Rows)
            {
                ///if (....)
                    joinTable.ImportRow(joinRows(r1,r2));
            }
        }
        return joinTable;
    }
    public DataRow joinRows (DataRow r1, DataRow r2)
    {
        DataRow joinRow = new DataRow();
        ///....
        return joinRow;
    }

【问题讨论】:

  • 基于什么标准?您希望输出是什么样的?
  • @DaveBish 标准不相关(“如果”)问题出在 joinrow() 中,我如何将一行与一行连接成一行
  • @iakovl2, the criteria is non relevant 简而言之,错误。当我有两行的架构匹配时,当列值不同时哪一行获胜?您正在创建一行
  • @MichaelPerrenoud 我错了,我想要一个简单的右/左连接...第 1 行是 1 2 3,第 2 行是 4 5 6,连接是 1 2 3 4 5 6跨度>
  • @iakovl2 你确定这是一个左/右连接吗?这些类型的连接仅从一侧或另一侧获取匹配行,并从相邻侧获取所有行。看起来你想要一个交叉连接。你能确认一下吗?

标签: c# join datatable datarow


【解决方案1】:

这是使用 LINQ 进行连接的两种方法的示例。

        var t1 = new DataTable();
        var t2 = new DataTable();
        t1.Columns.Add("id", typeof (Int32));
        t1.Columns.Add("data", typeof (String));
        t2.Columns.Add("id", typeof (Int32));
        t2.Columns.Add("data", typeof (Int32));

        t1.Rows.Add(new {id=1, data="John"});
        t1.Rows.Add(new {id = 2, data = "Mary"});

        t2.Rows.Add(new {id = 1, data = "100"});
        t2.Rows.Add(new {id = 2, data = "200"});


        var results = from x in t1.Select()
                      join y in t2.Select() on (Int32) x["id"] equals (Int32) y["id"]
                      select (new {id = x["id"], name = x["data"], number = y["data"]});

        var lamdaResults = t1.Select().Join(
            t2.Select(), x => x["id"], y => y["id"],
            (x, y) => new {id=x["id"], name=x["data"], number=y["data"]});

【讨论】:

  • 如果我知道每行中列的类型或数量。但在我的情况下,我不知道每个是什么(有几个表可供选择)
  • 那么你不应该使用“加入”这个词
【解决方案2】:

我认为您可能大大低估了您正在寻找的东西的复杂性,但这里有一些代码可以做到这一点,但我将讨论它的一些主要假设。

public DataTable joinTables (DataTable t1, DataTable t2)
{
    DataTable t = new DataTable();
    AddColumns(t1, t);
    AddColumns(t2, t);

    for (int i = 0; i < t1.Rows; i++)
    {
        DataRow newRow = t.NewRow();

        for (int j = 0; j < t1.Columns.Count; j++)
        {
            SetMergedRowValue(t1.Rows[i], newRow, j);
            SetMergedRowValue(t2.Rows[i], newRow, j);
        }

        t.Rows.Add(newRow);
    }

    t.AcceptChanges();
}

private void AddColumns(DataTable source, DataTable target)
{
    foreach (DataColumn c in source.Columns)
    {
        target.Columns.Add(string.Format("{0}_{1}", source.TableName, c.ColumnName), c.DataType);
    }
}

private void SetMergedRowValue(DataRow source, DataRow target, int index)
{
    var columnName = string.Format("{0}_{1}", source.Table.TableName, source.Table.Columns[index]);
    target[columnName] = source[index];
}

假设

  1. 每个DataTable 的行数相同。
  2. DataTable 对象中的行按照您希望它们按索引合并的顺序进行排序。

这些假设很重要。简而言之,虽然这会产生预期的结果,但我不确定它真的是您要寻找的,而且我不确定您是否真的确定您要什么'重新寻找。

【讨论】:

  • 这是一个太大的假设,我编写的程序就像一个哈希连接,将数据拆分到桶然后加入它们。
【解决方案3】:

好吧,你们这些疯子,我想我已经破解了。

这是我为我的问题想出的,做事的方式有点痛苦,但它使两个数据行合二为一,这正是我想要的。

找不到任何默认设置,但如果存在,请告诉我。

private DataRow JoinDataRow(DataRow r1, DataRow r2)
{
    // Get table columns
    var r1Cols = r1.Table.Columns;
    var r2Cols = r2.Table.Columns;

    // Create datatable to base row from
    var tempDataTable = new DataTable();
    foreach (DataColumn col in r1Cols)
    {
        tempDataTable.Columns.Add(new DataColumn(col.ColumnName, col.DataType, col.Expression, col.ColumnMapping));
    }

    foreach (DataColumn col in r2Cols)
    {
        tempDataTable.Columns.Add(new DataColumn(col.ColumnName, col.DataType, col.Expression, col.ColumnMapping));
    }

    // Create new return row to be returned
    DataRow returnRow = tempDataTable.NewRow();

    // Fill data
    int count = 0;
    for (int r1Index = 0; r1Index < r1Cols.Count; r1Index ++)
    {
        returnRow[r1Index] = r1[r1Index];
        count++;
    }

    for (int r2Index = count; r2Index < r2Cols.Count + count; r2Index++)
    {
        returnRow[r2Index] = r2[r2Index -count];
    }

    // Return row
    return returnRow;
}

您可以如何使用它的一个实例可能是使用 LINQ 将两个单独的数据表连接在一起,并且您希望行相应地采取行动,请参见下面的示例:

var memberCompanyDetails = 
    (from DataRow member in members.Rows
    join DataRow company in companies.Rows on member["company"] equals company["company"]
    select JoinDataRow(member, company)).AsEnumerable().CopyToDataTable();

【讨论】:

    猜你喜欢
    • 2019-01-14
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 2019-01-14
    • 2017-03-10
    • 2023-03-05
    • 2022-08-17
    相关资源
    最近更新 更多