【问题标题】:Is there an easy way to INNER join , OUTER join , LEFT OUTER join, RIGHT OUTER join, or UNION two (or more) DataTables in C#?在 C# 中是否有一种简单的方法来 INNER join 、 OUTER join 、 LEFT OUTER join 、 RIGHT OUTER join 或 UNION 两个(或更多)数据表?
【发布时间】:2016-07-27 20:14:24
【问题描述】:

我正在编写一个连接不同数据库系统的 C# 应用程序。这些系统可以是平面文件 db、Oracle、Sql、Excel 文件等。 C# 应用程序的工作是为在一个地方提供所有这些源代码提供一个出口。所以基本上,该应用程序接受相应数据库系统的查询和连接设置列表并收集一堆结果。

目标是输出一个单一的数据表,其中所有这些查询的结果都连接/联合在一起(取决于设置)。 C# 是否提供了一种简单的方法来对数据表列表执行任何联接/联合操作?

例如:

Table1:
__________________________________________________________
|tb1_pk_id|   tb1_name    |   tb1_data1   |   tb1_data2   |
|---------|---------------|---------------|---------------|
|    1    | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1  |
|    2    | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2  |
|    3    | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3  |
----------------------------------------------------------- 

Table2:
__________________________________________________________
|tb2_pk_id|   tb2_name    |   tb2_data1   |   tb2_data2   |
|---------|---------------|---------------|---------------|
|    1    | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1  |
|    2    | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2  |
|    3    | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3  |
----------------------------------------------------------- 

Join Results:
__________________________________________________________ _______________________________________________
|tb1_pk_id|   tb1_name    |   tb1_data1   |   tb1_data2   |   tb2_name    |   tb2_data1   |   tb2_data2   |
|---------|---------------|---------------|---------------|---------------|---------------|---------------|
|    1    | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1  | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1  |
|    2    | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2  | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2  |
|    3    | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3  | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3  |
-----------------------------------------------------------------------------------------------------------   

到目前为止,我在网上找到了以下代码 (here) 来对所有数据进行合并:

private DataTable MergeAll(IList<DataTable> tables, String primaryKeyColumn)
        {
            if (!tables.Any())
                throw new ArgumentException("Tables must not be empty", "tables");
            if (primaryKeyColumn != null)
                foreach (DataTable t in tables)
                    if (!t.Columns.Contains(primaryKeyColumn))
                        throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");

            if (tables.Count == 1)
                return tables[0];

            DataTable table = new DataTable("TblUnion");
            table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
            foreach (DataTable t in tables)
            {
                table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
            }
            table.EndLoadData();

            if (primaryKeyColumn != null)
            {
                // since we might have no real primary keys defined, the rows now might have repeating fields
                // so now we're going to "join" these rows ...
                var pkGroups = table.AsEnumerable()
                    .GroupBy(r => r[primaryKeyColumn]);
                var dupGroups = pkGroups.Where(g => g.Count() > 1);
                foreach (var grpDup in dupGroups)
                {
                    // use first row and modify it
                    DataRow firstRow = grpDup.First();
                    foreach (DataColumn c in table.Columns)
                    {
                        if (firstRow.IsNull(c))
                        {
                            DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
                            if (firstNotNullRow != null)
                                firstRow[c] = firstNotNullRow[c];
                        }
                    }
                    // remove all but first row
                    var rowsToRemove = grpDup.Skip(1);
                    foreach (DataRow rowToRemove in rowsToRemove)
                        table.Rows.Remove(rowToRemove);
                }
            }

            return table;
        }

这很适合做一个联合,但我不知道 .NET 中是否已经存在一种更简单的方法可以让我做 ANY 种类在一组单独的 DataTables 上加入或联合(不仅仅是上面代码中的联合)还是我必须自定义编码每种类型的加入/联合?

【问题讨论】:

    标签: c# .net join datatable


    【解决方案1】:

    不,没有一种简单的 .Net 方式可以做到这一点......

    LINQ 可以接近...您可以在 LINQ 中创建表连接,但它们通常是“内部连接”。执行“左连接”有点复杂,需要GroupJoin 关键字。 https://msdn.microsoft.com/en-us/library/bb386969(v=vs.110).aspx

    如果您想“自己动手”使用 ADO.Net DataRelations,您可以看看这篇旧的 VB.Net 文章:

    http://www.emmet-gray.com/Articles/DataRelations.html

    【讨论】:

    • 我感觉就是这种情况,我只是想确保我没有遗漏什么。我将研究使用 LINQ 方法。谢谢!
    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 2013-05-02
    • 2012-02-27
    • 1970-01-01
    • 2019-09-03
    • 2014-01-07
    • 2015-01-10
    • 2014-08-10
    相关资源
    最近更新 更多