目录
前言
最近使用ABP(ASP.NET Boilerplate)做项目,有些查询(或存储过程)直接使用sql语句会更方便一点。
定义一个接口
在Core项目中定义一个接口,如:ISqlExecuter
public interface ISqlExecuter { /// <summary> /// 执行给定的命令 /// </summary> /// <param name="sql">命令字符串</param> /// <param name="parameters">要应用于命令字符串的参数</param> /// <returns>执行命令后由数据库返回的结果</returns> int Execute(string sql, params object[] parameters); /// <summary> /// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。 /// </summary> /// <typeparam name="T">查询所返回对象的类型</typeparam> /// <param name="sql">SQL 查询字符串</param> /// <param name="parameters">要应用于 SQL 查询字符串的参数</param> /// <returns></returns> IQueryable<T> SqlQuery<T>(string sql, params object[] parameters); }
实现接口
项目中使用的是EF,因此在EntityFramework项目中实现该接口
public class SqlExecuter : ISqlExecuter, ITransientDependency { private readonly IDbContextProvider<XXXDbContext> _dbContextProvider; public SqlExecuter(IDbContextProvider<XXXDbContext> dbContextProvider) { _dbContextProvider = dbContextProvider; } /// <summary> /// 执行给定的命令 /// </summary> /// <param name="sql">命令字符串</param> /// <param name="parameters">要应用于命令字符串的参数</param> /// <returns>执行命令后由数据库返回的结果</returns> public int Execute(string sql, params object[] parameters) { return _dbContextProvider.DbContext.Database.ExecuteSqlCommand(sql, parameters); } /// <summary> /// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。 /// </summary> /// <typeparam name="T">查询所返回对象的类型</typeparam> /// <param name="sql">SQL 查询字符串</param> /// <param name="parameters">要应用于 SQL 查询字符串的参数</param> /// <returns></returns> public IQueryable<T> SqlQuery<T>(string sql, params object[] parameters) { return _dbContextProvider.DbContext.Database.SqlQuery<T>(sql, parameters).AsQueryable<T>(); } }
使用ITransientDependency接口abp会自动注册。
使用
我们一般会在Application项目中使用。
首先我们需要注入:
使用构造函数的方式注入
private readonly ISqlExecuter _sqlExecuter; public XXXAppService(ISqlExecuter sqlExecuter) { _sqlExecuter = sqlExecuter; }
使用IocManager注入
var sqlExecuter = IocManager.Instance.Resolve<ISqlExecuter>();
调用
public IEnumerable<OrderChartDto> GetOrderChartData() { const string sql = "select * from Orders"; var charts = _sqlExecuter.SqlQuery<OrderChartDto>(sql).ToList(); return charts; }
值得注意的是,调用代码需要工作单元的支持,Application中已默认支持,可直接使用。但如果在Controller中使用就需要将Action设置为UnitOfWork
[UnitOfWork] public virtual ActionResult GetOrderChartData() { .... }