关于泛型:将DataRow转换为类型T时,C#Int64Converter无法从System.Int64转换错误

C# Int64Converter cannot convert from System.Int64 error when converting DataRow to type T

我正在尝试将SQL表中的所有记录作为IEnumerable返回,例如,将电子邮件帐户表结果返回到电子邮件帐户的可枚举集合。我使用了一个名为selectall的方法,它执行一个SQL脚本,然后将数据表返回为可枚举的。

问题是,当试图使用getItem方法将Int64类型的表中的某些列转换为具有long类型匹配属性的t对象时,在"pro.setValue(obj,typeconverter.convertFrom(dr[column.columnname]),null);"行出现"Int64Converter cannot convert from system.int64"错误。

关于如何将表结果中的int64值转换为long属性有什么建议吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public void Test()
{
    var results = SelectAll<EmailAccount>();
    ....
}

public class EmailAccount
{
    public long Id { get; set; }
    public string Name { get; set; }
    public ImapEnum ImapType { get; set; }
}

public IEnumerable<T> SelectAll<T>() where T : new()
{
    var tableName ="EmailAccount"; // TableName<T>();

    var results = ExecuteReader($"SELECT * FROM {tableName};");

    if (results == null || results.Rows.Count == 0) return null;

    return results.AsEnumerable().Select(GetItem<T>);
}

private static T GetItem<T>(DataRow dr)
{
    var temp = typeof(T);
    var obj = Activator.CreateInstance<T>();

    foreach (DataColumn column in dr.Table.Columns)
    {
        foreach (var pro in temp.GetProperties())
        {
            if (pro.Name == column.ColumnName)
            {
                if (pro.PropertyType == typeof(Enum) || pro.PropertyType.BaseType == typeof(Enum))
                {
                    pro.SetValue(obj, Enum<StringComparison>.ToObject(dr[column.ColumnName]), null);
                }
                else
                {
                    var typeConverter = TypeDescriptor.GetConverter(pro.PropertyType);
                    pro.SetValue(obj, typeConverter.ConvertFrom(dr[column.ColumnName]), null);
                }                    
            }                        
            else
                continue;
        }
    }
    return obj;
}


Int64Converter只能作用于字符串对象。

This converter can only convert a 64-bit signed integer object to and from a string
https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.int64converter?redirectedfrom=MSDN&view=netframework-4.7.2#remarks

所以我建议你使用这个代码-

1
pro.SetValue(obj, typeConverter.ConvertFrom(dr[column.ColumnName].ToString()), null);


TypeConverter类通常用于Tstring之间的转换。在您的情况下,dr[column.ColumnName]中,column.ColumnNameId,结果已经准备好了long,因此不需要转换或铸造。如果类中包含数据库不支持的类型,那么将需要TypeConverter。这很可能是任何非原始类型。作为解决问题的方法,您可以使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var value = dr[column.ColumnName];

if (pro.PropertyType == typeof(Enum) || pro.PropertyType.BaseType == typeof(Enum))
{
    pro.SetValue(obj, Enum<StringComparison>.ToObject(value), null);
}  
else if(prop.PropertyType().IsAssignableFrom(value.GetType())
{
    pro.SetValue(obj, value);
}
else
{
    var typeConverter = TypeDescriptor.GetConverter(pro.PropertyType);
    pro.SetValue(obj, typeConverter.ConvertFrom(value), null);
}