我正在尝试准备一个字典,其中包含COLUMN_NAME
作为键,{IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH}
作为值。
这是我到目前为止所做的。
Dictionary<string, object> dict = new Dictionary<string, object>();
var dt = GetDataTable($"SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{tableName}'");
if (dt != null)
{
dict = dt.AsEnumerable().ToDictionary(row => row.Field<string>(0), row => new { IS_NULLABLE = row.Field<bool>(1), DATA_TYPE = row.Field<string>(2), CHARACTER_MAXIMUM_LENGTH = row.Field<int>(3) });
}
此处未列出的 GetDataTable
函数正常工作,并返回有效的System.Data.DataTable
。
编译器抛出......
错误CS0029:无法隐式转换类型&#39; System.Collections.Generic.Dictionary&gt;&#39;到&#39; System.Collections.Generic.Dictionary&#39;
问题是,如何使用这些属性生成匿名对象 -
IS_NULLABLE
,DATA_TYPE
,CHARACTER_MAXIMUM_LENGTH
?
答案 0 :(得分:3)
如果你没有在方法之外返回字典,则不需要声明它。
var dt = GetDataTable(@"SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{tableName}'");
var dict = dt?.AsEnumerable()?.ToDictionary(row => row.Field<string>(0), row => new { IS_NULLABLE = row.Field<bool>(1), DATA_TYPE = row.Field<string>(2), CHARACTER_MAXIMUM_LENGTH = row.Field<int>(3) });
您将获得Dictionary<string, anonymous type>
。
你可以使用你的类型:
if(dict["key"].IS_NULLABLE) MessageBox.Show("yeah....");
答案 1 :(得分:3)
在我看来,创建一个类DbColumn
会好得多。然后你的字典是Dictionary<string, DbColumn>
,你也可以将它作为字段使用或将其传递给其他方法,你不必每次都像Object
一样投射所有内容。您还可以使用其他属性或方法扩展该类。
但是,如果你只需要在该方法中使用这个字典,那么不将它存储在Dictionary<string, Object>
中以避免强制转换仍然会更好。
因此您可以使用var
:
var dt = GetDataTable($"SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{tableName}'");
if (dt != null)
{
var dict = dt.AsEnumerable().ToDictionary(row => row.Field<string>(0), row => new { IS_NULLABLE = row.Field<bool>(1), DATA_TYPE = row.Field<string>(2), CHARACTER_MAXIMUM_LENGTH = row.Field<int>(3) });
// here you can access all properties of the anonymous type without having to cast
}
当然,这只有在您需要在if
中使用时才有效。
答案 2 :(得分:1)
您必须明确地将您的匿名对象转换为object
类型:
dict = dt.AsEnumerable().ToDictionary(row => row.Field<string>(0), row => (object)new { IS_NULLABLE = row.Field<bool>(1), DATA_TYPE = row.Field<string>(2), CHARACTER_MAXIMUM_LENGTH = row.Field<int>(3) });
因为否则编译器会创建不同类型的字典。
答案 3 :(得分:1)
只需将新的匿名对象转换为object
,就不能将泛型类从一种类型转换为另一种类型。
dict = dt.AsEnumerable()
.ToDictionary(row => row.Field<string>(0),
row => (object)new // Here, we cast the result to object, so the dictionary will actually use the type 'object' and not 'anonymous type'
{
IS_NULLABLE = row.Field<bool>(1),
DATA_TYPE = row.Field<string>(2),
CHARACTER_MAXIMUM_LENGTH = row.Field<int>(3)
});
的确,您的ToDictionary
来电不会返回Dictionary<string, object>
,而是Dictionary<string, anonymous type>
。即使anonymous type
派生自object
,也无法使用泛型类型(因此,使用词典)进行强制转换。
您将无法使用object
访问匿名类型的属性,因此您应该使用dynamic
代替。