如何正确地将数据读取器转换为DTO/List
本文关键字:DTO List 转换 正确地 数据 读取 | 更新日期: 2023-09-27 18:32:10
我正在尝试找到一种将DataReader转换为DTO的简单方法(其属性就像列名一样)。但我想知道反射会如何影响性能,也许有一种更简单/更干净的方法可以做到这一点。
我正在查看SO,但没有找到像样的解决方案(即使在重复问题上)。
这是我为"家庭作业"所做的
public static T ConvertSPToDTO<T>(string procName, List<SqlParameter> parameters) where T : new()
{
T t = new T();
SqlDataReader rs = null;
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(procName, conn))
{
foreach (SqlParameter param in parameters)
{
cmd.Parameters.Add(param);
}
cmd.CommandType = CommandType.StoredProcedure;
rs = cmd.ExecuteReader();
List<string> columns = Enumerable.Range(0, rs.FieldCount).Select(rs.GetName).ToList();
while (rs.Read())
{
foreach (string column in columns)
{
if (rs[column] != System.DBNull.Value)
{
t.GetType().GetProperty(column).SetValue(t, Convert.ChangeType(rs[column], rs[column].GetType()), null);
}
}
}
rs.Close();
return t;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
finally
{
rs.Dispose();
}
}
为了有效地做到这一点,需要元编程。您可以使用库来提供帮助。例如,"FastMember"包括一个TypeAccessor,它提供对实例创建和按名称进行成员访问的快速访问。然而,这个例子基本上也是"dapper"的工作原理,所以你可以只使用dapper:
int id = ...
var data = connection.Query<Order>(
"select * from Orders where CustomerId = @id",
new { id }).ToList();
您还可以打开"dapper"代码以查看它的作用。