Как преобразовать результат хранимой процедуры в сущность - PullRequest
0 голосов
/ 21 января 2019

Я сейчас выполняю хранимую процедуру ниже, и она отлично работает.Но я не могу указать время ожидания команды.

 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 голосов
/ 21 января 2019

Я бы, честно говоря, перешёл как массив и преобразовал бы в табличный тип в SQL и сделал бы грязную работу на стороне сервера.Также хороший способ указать время ожидания можно сделать либо через строки подключения в вашем файле конфигурации, либо вы также можете передать этот же параметр в sql с задержкой WAITFOR.

Cheers!

0 голосов
/ 21 января 2019

Использование 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(); 
    }
}
0 голосов
/ 21 января 2019

Не так сложно, сделайте это так

обратите внимание, это ленивый eval, поэтому он должен хорошо работать, когда есть пользовательский ввод-вывод, все еще довольно быстро в других случаях, я использовал его впроекты данных 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...