如何将存储过程结果转换为实体

时间:2019-01-21 17:18:59

标签: c# sql-server entity-framework

我目前正在下面执行我的存储过程,它运行良好。但是我无法指定命令超时。

 var results = await _dbContext.DbContext.Database.SqlQuery<GetOutputDto>(@"[dbo].[GetOutput] " + parameterString, list.ToArray()).ToListAsync();

现在,我将其更改为以下内容,并想知道将结果转换为对象的最佳方法是什么。我有30多个属性,因此设置每个值将非常繁琐。想知道是否有一个干净的解决方案作为Entity Framework解决方案。

using (var conn = new SqlConnection(_dbContextProvider.DbContext.Database.Connection.ConnectionString))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand(@"[dbo].[GetOutput]", conn);
    cmd.CommandTimeout = 60;
    cmd.CommandType = CommandType.StoredProcedure;

    foreach (var item in list)
    {
        cmd.Parameters.Add(item);
    }

    cmd.ExecuteNonQuery();

    cmd.Connection.Close();

    // How to get the result to entity in a clean manner. 
}

3 个答案:

答案 0 :(得分:0)

没那么难,这样做

  

请注意,这是一个懒惰的评估,因此当有用户IO时它应该表现良好,在其他情况下仍然相当快,我已经在具有许多记录的数据ETL项目中使用了它。

public static IEnumerable<dynamic>( /* params */)
{
   // build command object here.

      using (SqlDataReader reader = cmd.ExecuteReader())
      {

        if (reader.Read())  // read the first one to get the columns collection
        {
          var cols = reader.GetSchemaTable()
                       .Rows
                       .OfType<DataRow>()
                       .Select(r => r["ColumnName"]);

          do
          {
            dynamic t = new System.Dynamic.ExpandoObject();

            foreach (string col in cols)
            {
              ((IDictionary<System.String, System.Object>)t)[col] = reader[col];
            }

            yield return t;
          } while (reader.Read());
        }
      }

   // remember to close connection
}

通过我的简单数据库框架https://gist.github.com/hoganlong/b7f5c5e8dde61ae3cd6f

答案 1 :(得分:0)

老实说,我会以数组的形式发送并转换为SQL中的表类型,并在服务器端进行肮脏的工作。同样,可以通过配置文件中的连接字符串来指定超时的一种好方法,也可以使用WAITFOR DELAY将相同的参数传递给sql。

干杯!

答案 2 :(得分:0)

在这种情况下使用System.reflection确实很方便。

public static List<T> Convert<T>(IDataReader dr) where T : class, new()
{
    List<T> list = new List<T>();
    T obj = default(T);
    while (dr.Read()) {
        obj = Activator.CreateInstance<T>();
        foreach (PropertyInfo prop in obj.GetType().GetProperties()) {
            if (!object.Equals(dr[prop.Name], DBNull.Value)) {
                prop.SetValue(obj, dr[prop.Name], null);
            }
        }
        list.Add(obj);
    }
    return list;
}


using (var conn = new SqlConnection(_dbContextProvider.DbContext.Database.Connection.ConnectionString))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand(@"[dbo].[GetOutput]", conn);
    cmd.CommandTimeout = 60;
    cmd.CommandType = CommandType.StoredProcedure;

    foreach (var item in list)
    {
        cmd.Parameters.Add(item);
    }

    using ( var reader = cmd.ExecuteReader() ){
    List<Entity> result = Convert<Entity>(reader); // convert to entity.
    cmd.Connection.Close(); 
    }
}