使用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实现此转换?
谢谢!
首先,使用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
语句中即可。