我正在使用带有abp(Asp.net BoilerPlate)框架的asp.net核心应用程序。我想使用存储过程来获取数据,并在此代码的第一个体系结构中实现CRUD操作。最好的方法是什么?
提前致谢
答案 0 :(得分:3)
以下是将参数发送到存储过程以删除用户的示例:
public async Task DeleteUser(EntityDto input) { await Context.Database.ExecuteSqlCommandAsync( "EXEC DeleteUserById @id", default(CancellationToken), new SqlParameter("id", input.Id) ); }
源代码发布于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/