检索单个对象的通用方法 c#
Generic method for retriving a single object c#
我研究这种方法有一段时间了,并试图弄清楚它是如何工作的。这显然适用于返回完美的对象列表。但我目前无法弄清楚的是如何检索单个对象,例如 "Employee e" 而不是 "List"?
public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
List<T> list = new List<T>();
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
直接打电话
var employee = table.DataTableToList<Employee>().FirstOrDefault();
或者(如果您的 DataTable
非常大),您可能希望使用 yield
关键字将扩展方法修改为 return 和 IEnumerable<T>
:
public static IEnumerable<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
yield return obj;
}
}
catch
{
yield break;
}
}
这样做的好处是该方法只会根据需要转换 table 中尽可能多的行。
只需在该方法 returns 的列表上使用兰巴表达式调用 FirstOrDefault。
因此,如果您正在寻找一个特定的 Employee 实例并且您在该对象上有一个 ID 属性,您将执行类似的操作。
var employee = employeeTableInstance.DataTableToList().FirstOrDefault(e => e.Id.Equals(id));
这不是提取单个对象的最有效方法,因为它需要您将整个 table 从行实例映射到对象实例,但如果您仍然需要 table 来列出功能出于其他原因并且无论如何都可能调用它,那么您可以采用这种方法。
如果您不需要它,那么如果您正在按主键搜索或查看查询表达式然后只映射一行而不是所有行,我会考虑调用 DataRowCollection 的 Find 方法。可以在此处找到查找和查询表达式的示例。 https://msdn.microsoft.com/en-us/library/y06xa2h1.aspx
我研究这种方法有一段时间了,并试图弄清楚它是如何工作的。这显然适用于返回完美的对象列表。但我目前无法弄清楚的是如何检索单个对象,例如 "Employee e" 而不是 "List"?
public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
List<T> list = new List<T>();
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
直接打电话
var employee = table.DataTableToList<Employee>().FirstOrDefault();
或者(如果您的 DataTable
非常大),您可能希望使用 yield
关键字将扩展方法修改为 return 和 IEnumerable<T>
:
public static IEnumerable<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
yield return obj;
}
}
catch
{
yield break;
}
}
这样做的好处是该方法只会根据需要转换 table 中尽可能多的行。
只需在该方法 returns 的列表上使用兰巴表达式调用 FirstOrDefault。
因此,如果您正在寻找一个特定的 Employee 实例并且您在该对象上有一个 ID 属性,您将执行类似的操作。
var employee = employeeTableInstance.DataTableToList().FirstOrDefault(e => e.Id.Equals(id));
这不是提取单个对象的最有效方法,因为它需要您将整个 table 从行实例映射到对象实例,但如果您仍然需要 table 来列出功能出于其他原因并且无论如何都可能调用它,那么您可以采用这种方法。
如果您不需要它,那么如果您正在按主键搜索或查看查询表达式然后只映射一行而不是所有行,我会考虑调用 DataRowCollection 的 Find 方法。可以在此处找到查找和查询表达式的示例。 https://msdn.microsoft.com/en-us/library/y06xa2h1.aspx