首页 > 数据库 >[EF Core] 多线程执行SQL Command

[EF Core] 多线程执行SQL Command

时间:2023-03-16 17:12:05浏览次数:36  
标签:Core Parameters EF 参数 任务 command context new 多线程

 

public class XXXRepository
{
   //数据库上下文
    private XXXDBContext context;

   //作用域服务工厂
    private readonly IServiceScopeFactory _serviceScopeFactory;

    public XXXRepository(XXXDBContext context, IServiceScopeFactory serviceScopeFactory)
    {
        this.context = context;
        _serviceScopeFactory = serviceScopeFactory;
    }

}

 

public void XXXMethod()
{
    // 开启数据库连接        
    context.Database.OpenConnection();

    // 多线程任务列表
    List<Task> tasks = new List<Task>();

    // 线程安全先进先出集合
    ConcurrentQueue<XXX> queue = new ConcurrentQueue<XXX>();
    
    // SQL参数列表 -- 任务公有参数
    List<SqlParameter> sqlParameters = new List<SqlParameter>(){
        (new SqlParameter("@参数1", "参数值"),
        (new SqlParameter("@参数2", "参数值"),
        (new SqlParameter("@参数3", "参数值")
    };
        
    // 循环创建任务
    XXXStringList.ForEach(paramater =>
    {
        // 任务私有参数
        // 因为任务将在ForEach执行完后才开始运行,这意味着所有任务将会使用同一个参数值
        // 所以需要使用一个变量来存储参数值,保证每个任务都使用独立的变量
        string param = paramater;

        // 添加任务到任务列表
        tasks.Add(

            // 创建并运行任务
            Task.Run(async () =>
            {

                try
                {
                    // 创建作用域服务
                    using (var scope = _serviceScopeFactory.CreateScope())
                    {
                        using (var _dbcontext = scope.ServiceProvider.GetService<XXXContext>())
                        {
                            using (var command = context.Database.GetDbConnection().CreateCommand())
                            {
                                command.Parameters.Clear();
                                
                                // 添加任务私有参数
                                command.Parameters.Add(new SqlParameter("@PARAM", param));
                        
                                // 添加任务公有参数
                                // 如果前面使用了SQL Command并且也使用了command.Parameters.Add()或command.Parameters.AddRange()
                                // 再次添加参数时可能会出现报错 -- The SqlParameter is already contained by another SqlParameterCollection
                                // 使用command.Parameters.Clear()似乎无法解决此问题
                                // 因此需要深度拷贝
                                command.Parameters.AddRange(sqlParameters.Select(s => ((ICloneable)s).Clone()).ToArray());

                                command.CommandText = "SELECT * FROM TABLE WHERE COLUMN = @PARAM AND ... ";
                                
                                // 有些查询语句在SQL Management Studio运行很快,但在代码中会出现超时
                                // 网上说是因为程序也占用了执行时间
                                // 这种情况可以添加CommandTimeout
                                command.CommandTimeout = 30000;

                                using (var res = await command.ExecuteReaderAsync())
                                {
                                    while (res.Read())
                                    {
                                        // 多任务执行时,插入数据可能会出现数据不一致性问题,就是每次的结果行数不一致
                                        // 使用线程安全先进先出集合,保证数据一致性
                                        queue.Enqueue(
                                            new XXX
                                            {
                                                Column1 = res[0].ToString(),
                                                Column2 = res[1].ToString(),
                                                Column3 = res[2].ToString(),
                                                ...
                                            };
                                        );

                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            })
        );

    });

    // 阻塞主线程,等待所有任务完成
    Task.WaitAll(tasks.ToArray());

    // 关闭数据库连接
    context.Database.CloseConnection();

}

 

标签:Core,Parameters,EF,参数,任务,command,context,new,多线程
From: https://www.cnblogs.com/WikiChen/p/17223350.html

相关文章

  • Sitecore DI
    依賴注入通過showconfig.aspx工具查看可參考系統自帶的配置文件寫法:<siteroot>\App_Config\Sitecore\ExperienceForms\Sitecore.ExperienceForms.Mvc.config<sitec......
  • C++11中的:移动语义(std::move)、完美转发(std::forward)、std::ref和std::cref
    左值(lvalue)与右值(rvalue)左值与右值的概念其实在C++0x中就有了。概括的讲,凡是能够取地址的可以称之为左值,反之称之为右值,C++中并没有对左值和右值给出明确的定义,从其......
  • 【JavaScript】用Object.definePropety()对对象的属性实现监听和修改_TA远方的博客
    本文中会讲到对象函数Object.defineProperty(),也许你对这个函数比较陌生,要知道这个函数用途可大了,等自己想到它的时候,就知道它的重要性。文章目录举个栗子赋值其它......
  • 【Java】CompletableFutureTimeoutUtils
    CompletableFutureTimeoutforJDK8importlombok.NonNull;importjava.util.ArrayDeque;importjava.util.Deque;importjava.util.concurrent.*;importjava.uti......
  • Sitecore Form 的使用
    下載安裝todo...使用文檔:https://doc.sitecore.com/xp/en/users/92/sitecore-experience-platform/sitecore-forms.html選擇Forms進入,創建自己的第一個form,......
  • .NET Core中的验证组件FluentValidation的实战分享
    今天有人问我能不能出一篇FluentValidation的教程,刚好今天在实现我们的.NETCore实战项目之CMS的修改密码部分的功能中有用到FluentValidation,所以就以修改用户密码为实例......
  • 极简实用的Asp.NetCore模块化框架决定免费开源了
    举报简介: 在开发这个框架之前,前前后后看过好几款模块化的框架,最后在一段时间内对ABPVNext痛下狠心,研究一段时间后,不得不说ABPVNext的代码层面很规范,也都是一些最佳实......
  • .Net Core微服务化ABP之六——处理Authentication
    上篇中我们已经可以实现sso,并且为各个服务集成sso认证。本篇处理权限系统的角色问题,权限系统分两层,第一层为整体系统角色权限,区分app用户、后台用户、网站用户的接口权限,第......
  • React之useEffect简记
    一.作用useEffectHook相当于componentDidMount,componentDidUpdate和componentWillUnmount这三个reactclass的生命周期函数的组合。componentDidMount:组件挂载;compone......
  • python爬虫增加多线程采集数据
    Python爬虫对于现如今大数据满天飞的时代来说真是如虎添翼,也越来越多的领域喜欢用Python来实现数据采集。像Scrapy、Request、BeautifuSoap、urlib等框架都可以实现自动爬......