【问题标题】:How to join two DataTables into another DataTable如何将两个数据表加入另一个数据表
【发布时间】:2019-05-24 03:33:16
【问题描述】:

我有两个数据表table1table2。我想加入它们,从而在C# 中生成另一个数据表。这两个表的所有列都是未知的。

这是我尝试过的:

var joinTables = from t1 in table1.AsEnumerable()
                 join t2 in table2.AsEnumerable() on t1["S_InstanceID"] equals t2["P_ID"]
                 select new { T1 = t1, T2 = t2 };

注意:两个表中没有同名列

table1 总是只有一行,但table2 可以有任意数量的行。

所有列都不知道,只有来自table1S_InstanceID 和来自table2P_ID 是已知的,它们必须用于连接关系

目前在joinTables var,我只得到anonymous DataRow - 我怎样才能以DataTable 格式获得它?

【问题讨论】:

  • 我需要同时添加它们 列合并用于DataTable的行合并
  • 对于连接,我们需要为两个表都有一个公共列,那么为什么它需要主键
  • Datatable.Merge(DataTable, Boolean, MissingSchemaAction) 不起作用?
  • 不知道@FalcoAlexander 但我需要添加它们 coulmwise
  • merge 将根据需要添加列,但表可能需要成为具有 FK 约束的 DataSet 的一部分。

标签: c# asp.net .net datatable


【解决方案1】:

我使用这种扩展方法将 LINQ 结果转换回DataTable,专门用于join

// Create new DataTable from LINQ results on DataTable
// Expect T to be anonymous object of form new { DataRow d1, DataRow d2, ... }
public static DataTable FlattenToDataTable<T>(this IEnumerable<T> src) {
    var res = new DataTable();
    if (src.Any()) {
        var firstRow = src.First();
        var rowType = typeof(T);
        var memberInfos = rowType.GetPropertiesOrFields();
        var allDC = memberInfos.SelectMany(mi => mi.GetValue<DataRow>(firstRow).Table.DataColumns());

        foreach (var dc in allDC) {
            var newColumnName = dc.ColumnName;
            if (res.ColumnNames().Contains(newColumnName)) {
                var suffixNumber = 1;
                while (res.ColumnNames().Contains($"{newColumnName}.{suffixNumber}"))
                    ++suffixNumber;
                newColumnName = $"{newColumnName}.{suffixNumber}";
            }
            res.Columns.Add(new DataColumn(newColumnName, dc.DataType));
        }

        foreach (var objRows in src)
            res.Rows.Add(memberInfos.SelectMany(mi => mi.GetValue<DataRow>(objRows).ItemArray).ToArray());
    }
    return res;
}

// ***
// *** Type Extensions
// ***
public static List<MemberInfo> GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
    t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field | mi.MemberType == MemberTypes.Property).ToList();

// ***
// *** MemberInfo Extensions
// ***
public static object GetValue(this MemberInfo member, object srcObject) {
    switch (member) {
        case FieldInfo mfi:
            return mfi.GetValue(srcObject);
        case PropertyInfo mpi:
            return mpi.GetValue(srcObject);
        default:
            throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
    }
}
public static T GetValue<T>(this MemberInfo member, object srcObject) => (T)member.GetValue(srcObject);

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2014-10-15
    • 2016-09-22
    相关资源
    最近更新 更多