首页 > 解决方案 > 在 C# 中非常频繁地将数据插入数据库

问题描述

有什么方法可以经常将数据保存/插入到数据库 vert 中?我有一个列表,其中包含 100 个学生记录的详细信息,例如姓名、年龄、班级等。实际上这些数据是从另一个网站获取的,我想将这些记录保存到 sql server 2012。SQLBulkCopy 不适合这个问题。

我正在使用如下所示的数据库查询:

            using (SqlConnection conn = new SqlConnection(DBHelper.DBConnection))
             {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {                     
                    cmd.CommandText = "insert into tableA.....";
                    cmd.ExecuteNonQuery();
                }
                conn.Close();
             }

目前我正在这样做 - 我从列表中获取第一个学生记录 [foreach(Student stud in list)] 并使用上述查询来保存每个学生。

如果我们经常使用sql连接打开和关闭,会不会有什么问题???

无论如何,我们可以非常频繁地将数据保存到数据库吗?

请帮忙。

标签: c#ado.net

解决方案


如果您将它们放在列表中,则可以将它们全部插入循环而不关闭连接。但是,打开和关闭与数据库的连接不会导致任何问题,只要在您完成关闭连接后正确处理它们即可。也就是说,您可以使用 Parallel.ForEach 调查项目的并行性:https ://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel- foreach-loophttps://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel.foreach?view=netcore-3.1。需要引用 System.Threading.Tasks 才能使用它。

编辑:关于如何使用 Parallel.ForEach 的一些示例代码:

using System;
using System.Threading;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Concurrent;

namespace WindowsFormsApp12
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // define the concurrent collection we'll use to leverage parallelism
        private ConcurrentBag<Student> allStudents = new ConcurrentBag<Student>();

        private void button1_Click(object sender, EventArgs e)
        {
            foreach(Student s in GetStudents())
            {
                // populate the concurrent collection with the student object
                // depending on how your code works, you may be able to modify the method that gets the data
                // from the web services to return this kind of collection and avoid this step
                allStudents.Add(s);
            }
            new Thread(() =>
            {
                Task.Run(() =>
                {
                    // MaxDegreeOfParallelism can be adjusted to suit your needs. We address the current Student
                    // object on the thread with the object s
                    Parallel.ForEach(allStudents, new ParallelOptions { MaxDegreeOfParallelism = 5 }, (s) =>
                     {
                         using (SqlConnection con = GetConnection())
                         {
                             using (SqlCommand cmd = new SqlCommand())
                             {
                                 cmd.Connection = con;
                                 cmd.CommandText = "INSERT INTO tblStudents ...";
                                 con.Open();
                                 cmd.ExecuteNonQuery();
                                 con.Close();
                             }
                         }
                     });
                    // you may want to clear the allStudents collection here if your code runs through this
                    // operation several times in a day
                }).Wait();
            }).Start();

        }

        private SqlConnection GetConnection()
        {
            // return a SqlConnection object wiht an appropriate connection string
            return new SqlConnection();
        }

        private List<Student> GetStudents()
        {
            // do something to populate the list
            return new List<Student>();
        }
    }

    public class Student
    {
        // class definition for the student object type
        public string Name { get; set; }
        public int Age { get; set; }
        public string Class { get; set; }
    }
}

推荐阅读