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

时间:2018-09-22 17:03:22

标签: c# generics

我试图以IEnumerable的形式从SQL表返回所有记录,例如电子邮件帐户表的结果为电子邮件帐户的可枚举集合。我使用一种称为SelectAll的方法,该方法执行SQL脚本,然后将DataTable返回为Enumerable。

问题是,当尝试使用GetItem方法将一些类型为Int64的匹配属性从Int64类型的表中的某些列转换为T对象时,出现错误' Int64Converter无法从System.Int64转换”位于行“ pro.SetValue(obj,typeConverter.ConvertFrom(dr [column.ColumnName]),null); ”。

关于如何将Int64值从表结果转换为long属性的任何建议?

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;
}

2 个答案:

答案 0 :(得分:2)

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

  

此转换器只能将64位带符号整数对象与字符串进行相互转换   https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.int64converter?redirectedfrom=MSDN&view=netframework-4.7.2#remarks

所以我建议您使用此代码-

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

答案 1 :(得分:1)

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

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);
}