WinForm里实现选择一个DataGridView指定行后同步到另外一个DataGridView中(基于Sql Server数据库)并批量插入数据库

using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using ConfigurationManagerSqlServerVersion.Helpers;
using MessageBoxer;

namespace ConfigurationManagerSqlServerVersion
{
    /// <summary>
    ///     WinForm里实现选择一个DataGridView指定行后同步到另外一个DataGridView中(基于Sql Server数据库)并批量插入数据
    ///     https://www.cnblogs.com/LifeDecidesHappiness/p/15457433.html
    ///     LDH @   2021-10-25
    /// </summary>
    public partial class FrmMain : Form
    {
        /// <summary>
        ///     数据库连接字符串
        /// </summary>
        public string ConnectionString = "Data Source =.; Initial Catalog = TestDB; User ID = sa; Password=123456";

        public FrmMain()
        {
            InitializeComponent();
            dgvBottom.CellValidating += DgvBottom_CellValidating;
            dgvBottom.CellEndEdit += DgvBottom_CellEndEdit;

            // 给DataGridView添加右键菜单
            dgvBottom.CellMouseDown += DgvBottom_CellMouseDown;
        }

        /// <summary>
        ///     在DataGridView控件上右键鼠标,弹出右键菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DgvBottom_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                if (e.RowIndex >= 0)
                {
                    // 若行已是选中状态就不再进行设置
                    if (dgvBottom.Rows[e.RowIndex].Selected == false)
                    {
                        dgvBottom.ClearSelection();
                        dgvBottom.Rows[e.RowIndex].Selected = true;
                    }

                    //弹出操作菜单
                    contextMenuStrip1.Show(MousePosition.X, MousePosition.Y);
                }
        }

        /// <summary>
        ///     单元格结束编辑事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DgvBottom_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            // Clear the row error in case the user presses ESC.   
            dgvBottom.Rows[e.RowIndex].ErrorText = string.Empty;

            //var dt = (DataTable)dgvBottom.DataSource;
        }

        /// <summary>
        ///     验证不能输入为空
        ///     https://vimsky.com/examples/detail/csharp-event-system.windows.forms.datagridview.cellendedit.html
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DgvBottom_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            var headerText = dgvBottom.Columns[e.ColumnIndex].HeaderText;

            // Abort validation if cell is not in the Type column.
            if (!headerText.Equals("Type")) return;

            // Confirm that the cell is not empty.
            if (string.IsNullOrEmpty(e.FormattedValue.ToString()))
            {
                dgvBottom.Rows[e.RowIndex].ErrorText = "Type Name must not be empty";
                e.Cancel = true;
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            BindData();
        }

        private void BindData()
        {
            dgvTop.DataSource = null;
            dgvTop.DataSource = GetDataSource();

            SetStyleForDataGridView(dgvTop, false);
        }

        /// <summary>
        ///     设置DataGridView样式
        /// </summary>
        /// <param name="dgv">DataGridView</param>
        /// <param name="canEditCell">是否可以编辑单元格</param>
        private void SetStyleForDataGridView(DataGridView dgv, bool canEditCell)
        {
            dgv.AllowUserToAddRows = false; // 不向用户显示添加行的选项
            dgv.AllowUserToResizeRows = false; // 禁止用户改变DataGridView所有行的行高  
            dgv.AutoGenerateColumns = false; // 禁止自动生成列
            dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect; //  整行选取
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 使数据区自动充满整个面板
            dgv.EditMode =
                canEditCell ? DataGridViewEditMode.EditOnEnter : DataGridViewEditMode.EditProgrammatically; // 是否可以编辑单元格

            dgv.ClearSelection(); // 取消选中状态
        }

        private DataTable GetDataSource()
        {
            var sql = "SELECT TOP 100 Name,Type,Year,Sponsor,Remark FROM dbo.CollegeInfo";
            var dt = SqlHelper.ExecuteDataset(ConnectionString, CommandType.Text, sql).Tables[0];
            return dt;
        }


        private void dgvTop_SelectionChanged(object sender, EventArgs e)
        {
            dgvBottom.DataSource = null;

            var totalDt = (DataTable)dgvTop.DataSource;

            // 选中Rows放在集合中
            var rowColls = dgvTop.SelectedRows;

            // 克隆一个表结构
            var selectedDt = totalDt.Clone();
            for (var i = 0; i < rowColls.Count; i++)
            {
                var dr = (rowColls[i].DataBoundItem as DataRowView)?.Row;
                selectedDt.ImportRow(dr);
            }

            dgvBottom.DataSource = selectedDt;

            SetStyleForDataGridView(dgvBottom, true);
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            var dr = ShowMessage.GetUserYesOrNo("您确定现在退出系统吗?", "温馨提示");
            if (dr == DialogResult.Yes)
                Environment.Exit(0);
            else
                e.Cancel = true;
        }

        /// <summary>
        ///     新增选中行记录到数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiInsert_Click(object sender, EventArgs e)
        {
            var dt = (DataTable)dgvBottom.DataSource;
            var result = BatchInsertIntoDatabase(dt);
            if (result)
            {
                ShowMessage.Notification("批量插入数据库表CollegeInfo中成功!");
                BindData();
            }
        }

        /// <summary>
        ///     一次性把DataTable中的数据插入数据库
        /// </summary>
        /// <param name="source">DataTable数据源</param>
        /// <returns>true - 成功,false - 失败</returns>
        public bool BatchInsertIntoDatabase(DataTable source)
        {
            SqlTransaction tran = null; // 声明一个事务对象
            try
            {
                using (var con = new SqlConnection(ConnectionString))
                {
                    con.Open(); // 打开数据库连接

                    using (tran = con.BeginTransaction())
                    {
                        using (var copy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, tran))
                        {
                            copy.DestinationTableName = "[CollegeInfo]"; // 指定服务器上目标表的名称
                            copy.WriteToServer(source); // 执行把DataTable中的数据写入DB  注意DataTable表结构要与数据库表结构一样
                            tran.Commit(); // 提交事务

                            return true; // 执行成功
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                tran?.Rollback();

                // 记录日志
                Console.WriteLine(ex.Message);

                return false;
            }
        }
    }
}
namespace ConfigurationManagerSqlServerVersion
{
    /// <summary>
    ///     CollegeInfo
    /// </summary>
    public class CollegeInfo
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public string Year { get; set; }
        public string Sponsor { get; set; }
        public string Remark { get; set; }
    }
}
/*
    SQL-建表CollegeInfo语句
*/

USE TestDB;
GO

IF EXISTS (SELECT * FROM sys.tables WHERE name = 'CollegeInfo')
BEGIN
    DROP TABLE CollegeInfo;
END;

CREATE TABLE CollegeInfo
(
    Name NVARCHAR(100) NOT NULL,
    Type NVARCHAR(10) NOT NULL,
    [Year] NVARCHAR(4) NOT NULL
        DEFAULT '2021',
    Sponsor NVARCHAR(100) NOT NULL,
    Remark NVARCHAR(MAX) NOT NULL
);

SELECT Name,
       Type,
       Year,
       Sponsor,
       Remark
FROM dbo.CollegeInfo;
踏实做一个为人民服务的搬运工!
原文地址:https://www.cnblogs.com/LifeDecidesHappiness/p/15457433.html