使用C#Linq';数据表中的ToDictionary

本文关键字:ToDictionary 数据表 C#Linq 使用 | 更新日期: 2023-09-27 18:22:51

我有一个sql查询,返回到DataTable:

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH 
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME IN (SELECT DBTABLE FROM MY_APP_SETTINGS)

这样,我想创建一个Dictionary<string, List<ColumnInfo>>,其中键是TABLE_NAME,ColumnInfo是一个自定义类,其属性与查询中返回的其他三个字段匹配。到目前为止,我有:

IEnumerable<DataRow> rows = MyDataTable.Rows.Cast<DataRow>();
var ExistingColumns = MyDataTable.AsEnumerable().Select(dataRow => rows
    .Select(row => new { 
        Key = row["TABLE_NAME"], 
        Value = new ColumnInfo(){ 
            ColumnName = row["COLUMN_NAME"].ToString(), 
            DataType = row["DATA_TYPE"].ToString(), 
            DataLength = int.Parse(row["DATA_LENGTH"].ToString())
        }
    }).ToDictionary(data => data.Key, data => data.Value));

然而,这有两个问题:1)存在重复的键,2)Value只是类的一个实例,而不是集合。

如何使用linq实现此转换?

谢谢!

使用C#Linq';数据表中的ToDictionary

首先,使用GroupBy按表名对行进行分组。这样可以确保表名是唯一的。

IEnumerable<DataRow> rows = MyDataTable.Rows.Cast<DataRow>();
Dictionary<string, List<ColumnInfo>> ExistingColumns = rows
    .GroupBy(r => r["TABLE_NAME"].ToString(),
             r => new ColumnInfo {
                 ColumnName = r["COLUMN_NAME"].ToString(),
                 DataType = r["DATA_TYPE"].ToString(),
                 DataLength = Int32.Parse(r["DATA_LENGTH"].ToString())
             }
        )
    .ToDictionary(g => g.Key, g => g.ToList());

分组依据的第一个参数选择键,第二个参数选择值。然后创建字典就很容易了。分组CCD_ 3是CCD_。因此,可以简单地使用g.ToList()创建列表。

ToDictionary()是一对一。

一对多是具有相同参数的ToLookup()

GSerg关于使用ToLookup的建议解决了密钥重复的问题。然而,为了演示如何实现这一点并获得Dictionary,您需要首先对表名进行分组,然后调用ToDictionary:

var query = MyDataTable.AsEnumerable()
                       .GroupBy(row => row["TABLE_NAME"].ToString())
                       .ToDictionary(g => g.Key,
    g => g.Select(row => new ColumnInfo()
    { 
        ColumnName = row["COLUMN_NAME"].ToString(), 
        DataType = row["DATA_TYPE"].ToString(), 
        DataLength = int.Parse(row["DATA_LENGTH"].ToString())
    }));

这将返回一个Dictionary<string, IEnumerable<ColumnInfo>>。如果您需要一个列表,只需将ToList()附加到Select语句中即可。