How to use Stored Procedure in asp.net core with boilerplate architecture?

拥有回忆 提交于 2019-12-13 02:47:58

问题


I am using asp.net core application with abp(Asp.net BoilerPlate) framework. I want to use stored procedure to get the data and also to implement CRUD operations in this code first architecture. What will be best way to do so?

Thanks in advance


回答1:


Here is an example that sends a parameter to a stored procedure to delete a user:

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

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

Source code is published on Github: https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/StoredProcedureDemo




回答2:


Create your custom repository, so you can access the dbcontext object and execute sql query by using this context. I have created some helper methods in my custom repository, hope it can help you:

 /// <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;
            }
        }

And in application service, inject your custom repository, and can call stored procedure like:

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



回答3:


If you dont want to use EF, you can use Dapper, it is easy to use: http://www.c-sharpcorner.com/article/asp-net-core-web-api-with-dapper-and-vs-2017/



来源:https://stackoverflow.com/questions/46337728/how-to-use-stored-procedure-in-asp-net-core-with-boilerplate-architecture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!