我试图以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;
}
答案 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
类通常用于在T
和string
之间进行转换。对于您的情况dr[column.ColumnName]
,其中column.ColumnName
是Id
,结果是已经是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);
}