【问题标题】:C# Int64Converter cannot convert from System.Int64 error when converting DataRow to type T将 DataRow 转换为 T 类型时,C# Int64Converter 无法从 System.Int64 错误转换
【发布时间】:2018-09-23 02:38:24
【问题描述】:

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

问题是当尝试使用 GetItem 方法将 Int64 类型的表中的某些列转换为具有 long 类型的匹配属性的 T 对象时,我收到错误“Int64Converter cannot convert from 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;
}

【问题讨论】:

    标签: c# generics


    【解决方案1】:

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

    【讨论】:

    • 没有意识到这一点。这对一些数据场景有帮助,谢谢。
    【解决方案2】:

    TypeConverter 类通常用于在Tstring 之间进行转换。在您的情况下 dr[column.ColumnName] 其中 column.ColumnNameId 结果 is 已经是 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);
    }   
    

    【讨论】:

    • 谢谢,添加 IsAssignableFrom 检查有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多