ABP中连接已有数据库执行Sql或存储过程

╄→尐↘猪︶ㄣ 提交于 2020-12-19 11:09:22

一:在EntityFramework项目中创建类如:ZSWDbContext。

public class ZSWDbContext : AbpDbContext
    {
        public ZSWDbContext() : base("ZSWConnectionString")
        {
            //这里设置不会执行
            //Database.SetInitializer<ZSWDbContext>(null);
        }
    }

二:在DataModule.cs类中设置DbContext在项目启动时不检测数据库的一致性。

否则会报The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations to update错误。

[DependsOn(typeof(AbpZeroEntityFrameworkModule), typeof(AmoiCoreModule))]
    public class AmoiDataModule : AbpModule
    {
        public override void PreInitialize()
        {
            Database.SetInitializer(new CreateDatabaseIfNotExists<AmoiDbContext>());
            Database.SetInitializer<ZSWDbContext>(null);
            Configuration.DefaultNameOrConnectionString = "Default";
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    }

三:在Core项目中定义执行Sql的接口:

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

然后在EntityFramework中实现该接口:

public class SqlExecuter : ISqlExecuter, ITransientDependency
    {
        private readonly IDbContextProvider<ZSWDbContext> _dbContextProvider;

        public SqlExecuter(IDbContextProvider<ZSWDbContext> 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.GetDbContext().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.GetDbContext().Database.SqlQuery<T>(sql, parameters).AsQueryable();
        }
    }

四:在构造函数中注入:

private readonly ISqlExecuter _sqlExecuter;
    public AppService(ISqlExecuter sqlExecuter)
    {
        _sqlExecuter = sqlExecuter;
    }

然后调用存储过程:

const string sql = "dbo.ResourceDataSync @STATION";
 var list = _sqlExecuter.SqlQuery<ResourceDataListDto>(sql, new SqlParameter("@STATION", "石家庄站")).ToList();

注意的地方:

ABP默认是开启事务的,如果在Service中同时调用不同的数据库,会出现 

服务器×××上的MSDTC不可用解决办法 错误,关闭事务即可解决:

[UnitOfWork(isTransactional: false)]

 

参考博客:

https://www.cnblogs.com/farb/p/sqlqueryinef.html

https://www.cnblogs.com/chiakiyu/p/5590211.html

 

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