如何在带有样板架构的asp.net核心中使用存储过程?

时间:2017-09-21 07:18:30

标签: stored-procedures asp.net-core code-first aspnetboilerplate

我正在使用带有abp(Asp.net BoilerPlate)框架的asp.net核心应用程序。我想使用存储过程来获取数据,并在此代码的第一个体系结构中实现CRUD操作。最好的方法是什么?

提前致谢

3 个答案:

答案 0 :(得分:3)

  

以下是将参数发送到存储过程以删除用户的示例:

public async Task DeleteUser(EntityDto input)
{
    await Context.Database.ExecuteSqlCommandAsync(
        "EXEC DeleteUserById @id",
        default(CancellationToken),
        new SqlParameter("id", input.Id)
    );
}

请参阅:Using Stored Procedure, User Defined Function and Views in a Custom Repository with ASP.NET Boilerplate

源代码发布于Github:https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/StoredProcedureDemo

答案 1 :(得分:0)

创建自定义存储库,以便可以使用此上下文访问dbcontext对象并执行sql查询。我在自定义存储库中创建了一些帮助方法,希望它可以帮助您:

 /// <summary>
 /// Map data from datareader to list object
 /// </summary>
 private List<T> MapToList<T>(DbDataReader reader)
        {
            var result = new List<T>();
            if (reader.HasRows)
            {
                var props = typeof(T).GetRuntimeProperties();
                var colMapping = reader.GetColumnSchema().Where(x => props.Any(p => p.Name.Equals(x.ColumnName, StringComparison.OrdinalIgnoreCase))).ToDictionary(key => key.ColumnName.ToLower());

                while (reader.Read())
                {
                    var item = Activator.CreateInstance<T>();
                    foreach (var prop in props)
                    {
                        var propValue = reader.GetValue(colMapping[prop.Name.ToLower()].ColumnOrdinal.Value);
                        prop.SetValue(item, propValue == DBNull.Value ? null : propValue);
                    }
                    result.Add(item);
                }
            }
            return result;
        }
/// <summary>
/// Execute command return empty result
/// </summary>
public int ExecuteSqlCommand(string sqlCommand, Dictionary<string, object> @params)
        {
            List<SqlParameter> sqlParams = new List<SqlParameter>();
            foreach (var item in @params)
            {
                if (item.Value != null)
                    sqlParams.Add(new SqlParameter(item.Key, item.Value));
                else
                    sqlParams.Add(new SqlParameter(item.Key, DBNull.Value));
            }

            if (@params.Count > 0)
                sqlCommand += " ";
            sqlCommand += String.Join(",", @params.Select(p => p.Key));
            return Context.Database.ExecuteSqlCommand(sqlCommand, sqlParams.ToArray());
        }
  /// <summary>
  /// Execute stored procedure return set of rows
  /// </summary>
  public IEnumerable<TResult> ExecuteStoredProcedureWithRowsResult<TResult>(string name, Dictionary<string, object> @params) where TResult : class
        {
            //Fix exception: ExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction.  The Transaction property of the command has not been initialized.
            UnitOfWorkManager.Current.Options.IsTransactional = false;
            using (var command = Context.Database.GetDbConnection().CreateCommand())
            {
                var result = new List<TResult>();
                string sqlCmd = String.Format("{0} ", name);
                if (command.Connection.State != System.Data.ConnectionState.Open)
                    command.Connection.Open();
                try
                {
                    foreach (var item in @params)
                    {
                        if (item.Value != null)
                            command.Parameters.Add(new SqlParameter(item.Key, item.Value));
                        else
                            command.Parameters.Add(new SqlParameter(item.Key, DBNull.Value));

                        command.CommandText = sqlCmd;
                        command.CommandType = System.Data.CommandType.StoredProcedure;
                        using (var reader = command.ExecuteReader())
                        {
                            result = MapToList<TResult>(reader);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    command.Connection.Close();
                }

                return result;
            }
        }

在应用程序服务中,注入自定义存储库,并可以调用存储过程,如:

var @params = new Dictionary<string, object>();
@params.Add("Id", 1);
var result = _customRepository.ExecuteStoredProcedureWithRowsResult<UserResult>("sp_getUsers", @params);

答案 2 :(得分:0)

如果你不想使用EF,你可以使用Dapper,它很容易使用:http://www.c-sharpcorner.com/article/asp-net-core-web-api-with-dapper-and-vs-2017/