C# C语言中数据表的内部联接#

C# C语言中数据表的内部联接#,c#,join,datatable,inner-join,C#,Join,Datatable,Inner Join,设T1和T2是带有以下字段的DataTables T1(CustID, ColX, ColY) T2(CustID, ColZ) 我需要一张桌子 TJ (CustID, ColX, ColY, ColZ) 如何在C代码中以简单的方式实现这一点?谢谢。如果允许您使用LINQ,请查看以下示例。它创建两个具有整数列的数据表,用一些记录填充它们,使用LINQ查询连接它们,并将它们输出到控制台 DataTable dt1 = new DataTable(); dt1.Columns.

设T1和T2是带有以下字段的
DataTable
s

T1(CustID, ColX, ColY)

T2(CustID, ColZ)
我需要一张桌子

TJ (CustID, ColX, ColY, ColZ)

如何在C代码中以简单的方式实现这一点?谢谢。

如果允许您使用LINQ,请查看以下示例。它创建两个具有整数列的数据表,用一些记录填充它们,使用LINQ查询连接它们,并将它们输出到控制台

    DataTable dt1 = new DataTable();
    dt1.Columns.Add("CustID", typeof(int));
    dt1.Columns.Add("ColX", typeof(int));
    dt1.Columns.Add("ColY", typeof(int));

    DataTable dt2 = new DataTable();
    dt2.Columns.Add("CustID", typeof(int));
    dt2.Columns.Add("ColZ", typeof(int));

    for (int i = 1; i <= 5; i++)
    {
        DataRow row = dt1.NewRow();
        row["CustID"] = i;
        row["ColX"] = 10 + i;
        row["ColY"] = 20 + i;
        dt1.Rows.Add(row);

        row = dt2.NewRow();
        row["CustID"] = i;
        row["ColZ"] = 30 + i;
        dt2.Rows.Add(row);
    }

    var results = from table1 in dt1.AsEnumerable()
                 join table2 in dt2.AsEnumerable() on (int)table1["CustID"] equals (int)table2["CustID"]
                 select new
                 {
                     CustID = (int)table1["CustID"],
                     ColX = (int)table1["ColX"],
                     ColY = (int)table1["ColY"],
                     ColZ = (int)table2["ColZ"]
                 };
    foreach (var item in results)
    {
        Console.WriteLine(String.Format("ID = {0}, ColX = {1}, ColY = {2}, ColZ = {3}", item.CustID, item.ColX, item.ColY, item.ColZ));
    }
    Console.ReadLine();

// Output:
// ID = 1, ColX = 11, ColY = 21, ColZ = 31
// ID = 2, ColX = 12, ColY = 22, ColZ = 32
// ID = 3, ColX = 13, ColY = 23, ColZ = 33
// ID = 4, ColX = 14, ColY = 24, ColZ = 34
// ID = 5, ColX = 15, ColY = 25, ColZ = 35
DataTable dt1=newdatatable();
dt1.Columns.Add(“CustID”,typeof(int));
dt1.Columns.Add(“ColX”,typeof(int));
dt1.Columns.Add(“ColY”,typeof(int));
DataTable dt2=新的DataTable();
dt2.Columns.Add(“CustID”,typeof(int));
添加(“ColZ”,typeof(int));

对于(int i=1;i我想要一个可以连接表的函数,而不需要您使用匿名类型选择器定义列,但很难找到任何一个。我最终不得不自己创建一个。希望这将有助于将来搜索此函数的任何人:

private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func<DataRow, DataRow, bool>[] joinOn)
{
    DataTable result = new DataTable();
    foreach (DataColumn col in t1.Columns)
    {
        if (result.Columns[col.ColumnName] == null)
            result.Columns.Add(col.ColumnName, col.DataType);
    }
    foreach (DataColumn col in t2.Columns)
    {
        if (result.Columns[col.ColumnName] == null)
            result.Columns.Add(col.ColumnName, col.DataType);
    }
    foreach (DataRow row1 in t1.Rows)
    {
        var joinRows = t2.AsEnumerable().Where(row2 =>
            {
                foreach (var parameter in joinOn)
                {
                    if (!parameter(row1, row2)) return false;
                }
                return true;
            });
        foreach (DataRow fromRow in joinRows)
        {
            DataRow insertRow = result.NewRow();
            foreach (DataColumn col1 in t1.Columns)
            {
                insertRow[col1.ColumnName] = row1[col1.ColumnName];
            }
            foreach (DataColumn col2 in t2.Columns)
            {
                insertRow[col2.ColumnName] = fromRow[col2.ColumnName];
            }
            result.Rows.Add(insertRow);
        }
    }
    return result;
}
专用数据表JoinDataTables(数据表t1、数据表t2、参数Func[]joinOn)
{
DataTable结果=新DataTable();
foreach(t1.Columns中的数据列col)
{
if(result.Columns[col.ColumnName]==null)
result.Columns.Add(col.ColumnName,col.DataType);
}
foreach(t2.Columns中的数据列col)
{
if(result.Columns[col.ColumnName]==null)
result.Columns.Add(col.ColumnName,col.DataType);
}
foreach(t1.Rows中的数据行第1行)
{
var joinRows=t2.AsEnumerable()。其中(row2=>
{
foreach(joinOn中的var参数)
{
如果(!参数(第1行,第2行))返回false;
}
返回true;
});
foreach(joinRows中的DataRow fromRow)
{
DataRow insertRow=result.NewRow();
foreach(t1.Columns中的数据列col1)
{
insertRow[col1.ColumnName]=行1[col1.ColumnName];
}
foreach(t2.Columns中的数据列col2)
{
insertRow[col2.ColumnName]=fromRow[col2.ColumnName];
}
result.Rows.Add(insertRow);
}
}
返回结果;
}
您可能如何使用此功能的示例:

var test = JoinDataTables(transactionInfo, transactionItems,
               (row1, row2) =>
               row1.Field<int>("TransactionID") == row2.Field<int>("TransactionID"));
var test=JoinDataTables(transactionInfo、transactionItems、,
(第1行,第2行)=>
行1.Field(“TransactionID”)==行2.Field(“TransactionID”);

一个警告:这当然不是优化的,所以当达到20k以上的行数时要小心。如果你知道一个表比另一个表大,试着先放小的一个表,再放大的一个表。

这是我的代码。虽然不完美,但效果很好。我希望它能帮助某些人:

    static System.Data.DataTable DtTbl (System.Data.DataTable[] dtToJoin)
    {
        System.Data.DataTable dtJoined = new System.Data.DataTable();

        foreach (System.Data.DataColumn dc in dtToJoin[0].Columns)
            dtJoined.Columns.Add(dc.ColumnName);

        foreach (System.Data.DataTable dt in dtToJoin)
            foreach (System.Data.DataRow dr1 in dt.Rows)
            {
                System.Data.DataRow dr = dtJoined.NewRow();
                foreach (System.Data.DataColumn dc in dtToJoin[0].Columns)
                    dr[dc.ColumnName] = dr1[dc.ColumnName];

                dtJoined.Rows.Add(dr);
            }

        return dtJoined;
    }

此函数将使用一个已知的联接字段联接两个表,但除了联接字段外,这不能允许两个表上有两个同名字段,一个简单的修改是用计数器保存一个字典,只需将数字添加到同名字段

public static DataTable JoinDataTable(DataTable dataTable1, DataTable dataTable2, string joinField)
{
    var dt = new DataTable();
    var joinTable = from t1 in dataTable1.AsEnumerable()
                            join t2 in dataTable2.AsEnumerable()
                                on t1[joinField] equals t2[joinField]
                            select new { t1, t2 };

    foreach (DataColumn col in dataTable1.Columns)
        dt.Columns.Add(col.ColumnName, typeof(string));

    dt.Columns.Remove(joinField);

    foreach (DataColumn col in dataTable2.Columns)
        dt.Columns.Add(col.ColumnName, typeof(string));

    foreach (var row in joinTable)
    {
        var newRow = dt.NewRow();
        newRow.ItemArray = row.t1.ItemArray.Union(row.t2.ItemArray).ToArray();
        dt.Rows.Add(newRow);
    }
    return dt;
}

我试着用另一种方法来做这件事

public static DataTable JoinTwoTables(DataTable innerTable, DataTable outerTable)
        {
            DataTable resultTable = new DataTable();
            var innerTableColumns = new List<string>();
            foreach (DataColumn column in innerTable.Columns)
            {
                innerTableColumns.Add(column.ColumnName);
                resultTable.Columns.Add(column.ColumnName);
            }

            var outerTableColumns = new List<string>();
            foreach (DataColumn column in outerTable.Columns)
            {
                if (!innerTableColumns.Contains(column.ColumnName))
                {
                    outerTableColumns.Add(column.ColumnName);
                    resultTable.Columns.Add(column.ColumnName);
                }                    
            }

            for (int i = 0; i < innerTable.Rows.Count; i++)
            {
                var row = resultTable.NewRow();
                innerTableColumns.ForEach(x =>
                {
                    row[x] = innerTable.Rows[i][x];
                });
                outerTableColumns.ForEach(x => 
                {
                    row[x] = outerTable.Rows[i][x];
                });
                resultTable.Rows.Add(row);
            }
            return resultTable;
        }
公共静态DataTable JoinTwoTables(DataTable innerTable,DataTable outerTable)
{
DataTable resultTable=新DataTable();
var innerTableColumns=新列表();
foreach(innerTable.Columns中的DataColumn列)
{
innerTableColumns.Add(column.ColumnName);
resultTable.Columns.Add(column.ColumnName);
}
var outerTableColumns=新列表();
foreach(outerTable.Columns中的DataColumn列)
{
如果(!innerTableColumns.Contains(column.ColumnName))
{
outerTableColumns.Add(column.ColumnName);
resultTable.Columns.Add(column.ColumnName);
}                    
}
for(int i=0;i
{
行[x]=innerTable.Rows[i][x];
});
outerTableColumns.ForEach(x=>
{
行[x]=可外接。行[i][x];
});
可结果.Rows.Add(row);
}
返回结果;
}

有没有办法修改它,以便在多个“加入”条件之间指定AND或or运算符?最简单的方法是不更改代码,只将所有条件打包为一个加入条件。例如:
row1.Field(“Id”)==row2.Field(“Id”)| row1.Field(“CustId”)==row2.Field(“CustId”)
但是,您将无法动态指定逻辑运算符。这并不完全正确,尽管它确实变得非常难看:
(useAnd&&row1.Field(“Id”)==row2.Field(“Id”)&&row1.Field(“CustId”)==row2.Field(“CustId”)|(!useAnd&&row1.Field(“Id”)==row2.Field(“Id”)| row1.Field(“CustId”)==row2.Field(“CustId”))
实际上,如果你的连接谓词中有任何复杂的规则,你应该只使用一个谓词,将所有规则都塞进其中(可能会被拉到它自己的函数中,以使代码看起来更漂亮)。这最终对我起到了作用,但我花了一个多小时在它上面,除了“指定的强制转换无效”,质疑我的理智,直到我将其从(int)table1[“field”]更改为Convert.ToInt32(table1[“field”])。@CindyH,非常感谢您的评论,它节省了我的时间。我想这是因为System.Data.DataTypes,其中不包括int,但Int32是。此处列出了所有数据类型: