zoukankan      html  css  js  c++  java
  • EntityFramework更新多条数据【8万】

    此文主要用做记录用:

    原因:数据库迁移,需要转换大量用户资料,两数据某字段加密方式不一致需要批量转换

    注:转换程序用了EntityFramework

    过程:

    1.读取所有需要转换数据至List

    2.采用Parallel.ForEach对List进行批次数据转换

    3.将转换后的List数据按一定数量进行分割为List<List<T>>

    4.建立List<List<T>>相应数量Task数组

    5.采用Task.Run建立写入数据库Action

    5.运行所有Task[],指令为Task.WaitAll(tasks);

    总结:主要是针对写入数据库进行多线程方式处理,读取目前还能忍受,当时用foreach一笔笔写入程序直接假死,半天没反应,后采用多线程写入,效果非常明显

    附代码如下:

    List<TableName> query;
    Stopwatch watch = new Stopwatch();
    watch.Start();
    using (DataBaseConext db = new DataBaseConext())
    {
        db.Configuration.ValidateOnSaveEnabled = false;
        query = db.apuser.Where(p => p.unpwd != "").ToList();
    }
    watch.Stop();
    MessageBox.Show(String.Format("读取使用秒数:{0}", watch.Elapsed.TotalSeconds));
    
    watch.Restart();
    Parallel.ForEach<TableName>(query, p =>
    {
        //SomethingCode
    });
    
    watch.Stop();
    MessageBox.Show(String.Format("轉換使用秒數:{0}", watch.Elapsed.TotalSeconds));
    
    watch.Restart();
    List<List<TableName>> users = new List<List<TableName>>();
    int splitCount = 1000;
    while (query.Any())
    {
        users.Add(query.Take(splitCount).ToList());
        query = query.Skip(splitCount).ToList();
    }
    
    Task[] tasks = new Task[users.Count()];
    for (int ctr = 0; ctr < users.Count(); ctr++)
    {
        var s = users[ctr];
        tasks[ctr] = Task.Run(() =>
        {
            using (DataBaseConext db = new DataBaseConext())
            {
                db.Configuration.ValidateOnSaveEnabled = false;
                db.Configuration.AutoDetectChangesEnabled = false;
                s.ForEach(p =>
                {
                    db.Entry<TableName>(p).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
    
                    Debug.WriteLine(String.Format("當前線程編號:{0}", Thread.CurrentThread.ManagedThreadId));
                });
            }
        });
    }
    Task.WaitAll(tasks);
    watch.Stop();
    MessageBox.Show(String.Format("分割及保存使用秒數:{0}", watch.Elapsed.TotalSeconds));
    
    MessageBox.Show("完成");
  • 相关阅读:
    gc buffer busy/gcs log flush sync与log file sync
    给Oracle年轻的初学者的几点建议
    Android 编程下帧动画在 Activity 启动时自动运行的几种方式
    Android 编程下 Touch 事件的分发和消费机制
    Java 编程下 static 关键字
    Java 编程下 final 关键字
    Android 编程下模拟 HOME 键效果
    Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
    Extjs4 大型项目目录结构重构
    [转]SQLServer 2008 允许远程连接的配置方法
  • 原文地址:https://www.cnblogs.com/ywkpl/p/4471944.html
Copyright © 2011-2022 走看看