【问题标题】:How to use Stored Procedure in asp.net core with boilerplate architecture?如何在具有样板架构的 asp.net 核心中使用存储过程?
【发布时间】:2017-09-21 07:18:30
【问题描述】:

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

提前致谢

【问题讨论】:

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


【解决方案1】:

这是一个向存储过程发送参数以删除用户的示例:

公共异步任务 DeleteUser(EntityDto 输入)
{
    等待 Context.Database.ExecuteSqlCommandAsync(
        "EXEC DeleteUserById @id",
        默认(取消令牌),
        新的 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

【讨论】:

    【解决方案2】:

    创建您的自定义存储库,以便您可以访问 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);
    

    【讨论】:

      【解决方案3】:

      【讨论】:

        猜你喜欢
        • 2021-10-24
        • 1970-01-01
        • 2016-09-18
        • 1970-01-01
        • 1970-01-01
        • 2019-07-13
        • 2019-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多