2013-09-21 42 views
2

我试图找到一个简单的方法来将DataReader转换为DTO(它的属性就像列名称一样)。但我想知道反射如何影响性能,也许有一种更简单/更清洁的方式来做到这一点。如何正确地将DataReader转换为DTO/List <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(); 
     } 
    } 
+1

你可以使用AutoMapper(https://github.com/AutoMapper/AutoMapper)。 – kmatyaszek

回答

1

为了有效地做到这一点,需要元编程。您可以使用库来提供帮助。例如,“FastMember”包含一个TypeAccessor,它可以按名称快速访问实例创建和成员访问。然而,这个例子也基本上究竟是如何“短小精悍”的作品,所以你可以只使用短小精悍

int id = ... 
var data = connection.Query<Order>(
    "select * from Orders where CustomerId = @id", 
    new { id }).ToList(); 

您也可以开辟“短小精悍”的代码,看看它做什么。

相关问题