我正在尝试使用以下方法填充数据表中的对象列表
public static List<T> toList<T>(this DataTable table) where T : new()
{
try
{
List<T> list = new List<T>();
foreach (var row in table.AsEnumerable())
{
var obj = new T();
foreach (var prop in typeof(T).GetProperties())
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
Type targetType = propertyInfo.PropertyType;
if (table.Columns.Contains(prop.Name))
{
try
{
object value = row[prop.Name];
if (value != null)
{
if (value.GetType() == typeof(string))
{
if (string.IsNullOrWhiteSpace(value.ToString()))
{
value = null;
}
}
if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
targetType = Nullable.GetUnderlyingType(targetType);
}
value = Convert.ChangeType(value, targetType);
propertyInfo.SetValue(obj, value);
}
}
catch
{
continue;
}
}
}
list.Add(obj);
}
return list;
}
catch (Exception ex)
{
return null;
}
}
我有以下型号
public class A
{
public string str1 {get;set;}
public int int1 {get;set;}
public DateTime dateTime1 {get;set;}
}
public class B
{
public string str2 {get;set;}
public int int2 {get;set;}
public DateTime dateTime2 {get;set;}
public A vara {get;set;}
}
我的数据表如下
+-----------+-----------+-----------+-----------+---------------+---------------+
| str1 | str2 | int1 | int2 | dateTime1 | dateTime2 |
+-----------+-----------+-----------+-----------+---------------+---------------+
| "abc" | "def" | 1 | 2 | NULL | NULL |
+-----------+-----------+-----------+-----------+---------------+---------------+
如果我使用,所有这些都可以正常工作
List<B> list = dataTable.toList<B>();
但是我也想在列表的每个元素中设置vara的值。
如何检查类型是否为自定义类型? 我不能使用Type.IsClass,因为它也适用于字符串。 如果我可以检测到某个属性属于“自定义类类型”,则可以使用相同的方法填充该值。 我希望我已经解释清楚了。
答案 0 :(得分:0)
我能够创建以下通用解决方案
public static List<T> toList<T>(this DataTable table) where T : new()
{
try
{
var list = table.toList(typeof(T));
var newLIst = list.Cast<T>().ToList();
return newLIst;
}
catch
{
return null;
}
}
public static List<object> toList(this DataTable table, Type type)
{
try
{
List<object> list = new List<object>();
foreach (var row in table.AsEnumerable())
{
var obj = row.toObject(type);
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
public static object toObject(this DataRow row, Type type, string sourcePropName = "")
{
try
{
var obj = Activator.CreateInstance(type);
var props = type.GetProperties();
foreach (var prop in props)
{
PropertyInfo propertyInfo = type.GetProperty(prop.Name);
Type targetType = propertyInfo.PropertyType;
string propName = prop.Name;
if (!string.IsNullOrWhiteSpace(sourcePropName))
{
propName = sourcePropName + "__" + propName;
if (!row.Table.Columns.Contains(propName))
{
propName = prop.Name;
}
}
if (row.Table.Columns.Contains(propName))
{
try
{
object value = row[propName];
if (value != null)
{
if (value.GetType() == typeof(string))
{
if (string.IsNullOrWhiteSpace(value.ToString()))
{
value = null;
}
}
targetType = targetType.handleNullableType();
value = Convert.ChangeType(value, targetType);
propertyInfo.SetValue(obj, value);
}
}
catch
{
continue;
}
}
else
if (targetType.IsClass && targetType != typeof(string))
{
if (targetType.IsGenericList())
{
Type ltype = targetType.GetProperty("Item").PropertyType;
object value = row.toObject(ltype, propName);
if (value == null)
{
continue;
}
var valList = new List<object> { value }.ConvertList(targetType);
try
{
propertyInfo.SetValue(obj, valList);
}
catch (Exception ex)
{
log.Error(ex);
}
}
else
{
object value = row.toObject(targetType, propName);
propertyInfo.SetValue(obj, value);
}
}
}
return obj;
}
catch
{
return null;
}
}
public static object ConvertList(this List<object> value, Type type)
{
IList list = (IList)Activator.CreateInstance(type);
foreach (var item in value)
{
list.Add(item);
}
return list;
}
为了填充B类的所有属性(包括vara属性),我必须在属于vara属性的列的名称前面加上分隔符 ___
因此,关于表应如下所示
+-----------------+-----------+-----------------+-----------+---------------------+---------------+
| vara__str1 | str2 | vara__int1 | int2 | vara__dateTime1 | dateTime2 |
+-----------------+-----------+-----------------+-----------+---------------------+---------------+
| "abc" | "def" | 1 | 2 | NULL | NULL |
+-----------------+-----------+-----------------+-----------+---------------------+---------------+