C# 使用DataTable插入或更新SQL表

C# 使用DataTable插入或更新SQL表,c#,asp.net,sql-server,C#,Asp.net,Sql Server,首先,我不能使用任何存储过程或视图。 我知道这似乎适得其反,但这不是我的规则 我有一个数据表,里面装满了数据。它有一个复制到我的SQL表的结构 ID-名称 SQL表当前有一些数据,但我现在需要用我的DataTable的所有数据更新它。如果ID匹配,则需要更新SQl表,或者将其添加到唯一的列表中 有没有办法只在我的WinForm应用程序中执行此操作 到目前为止,我已经: SqlConnection sqlConn = new SqlConnection(ConnectionString);

首先,我不能使用任何存储过程或视图。
我知道这似乎适得其反,但这不是我的规则

我有一个
数据表
,里面装满了数据。它有一个复制到我的SQL表的结构

ID-名称

SQL表当前有一些数据,但我现在需要用我的
DataTable
的所有数据更新它。如果ID匹配,则需要更新SQl表,或者将其添加到唯一的列表中

有没有办法只在我的WinForm应用程序中执行此操作

到目前为止,我已经:

SqlConnection sqlConn = new SqlConnection(ConnectionString);
            SqlDataAdapter adapter = new SqlDataAdapter(string.Format("SELECT * FROM {0}", cmboTableOne.SelectedItem), sqlConn);
            using (new SqlCommandBuilder(adapter))
            {
                try
                {
                    adapter.Fill(DtPrimary);
                    sqlConn.Open();
                    adapter.Update(DtPrimary);
                    sqlConn.Close();
                }
                catch (Exception es)
                {
                    MessageBox.Show(es.Message, @"SQL Connection", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
数据表:

        DataTable dtPrimary = new DataTable();

        dtPrimary.Columns.Add("pv_id");
        dtPrimary.Columns.Add("pv_name");

        foreach (KeyValuePair<int, string> valuePair in primaryList)
        {
            DataRow dataRow = dtPrimary.NewRow();

            dataRow["pv_id"] = valuePair.Key;
            dataRow["pv_name"] = valuePair.Value;

            dtPrimary.Rows.Add(dataRow);

由于要更新现有值并从包含所有数据的datatable中插入新值,我认为以下方法可能最适合您:

  • 从SQL表中删除所有现有数据(可以使用TSQL语句提高速度和效率)
  • 使用ADO.NET
    sqlbulcopy
    类使用方法将数据从ADO.NET表大容量插入SQL表

  • 没有涉及视图或存储过程,只涉及纯TSQL和.NET代码。

    这是我的尝试,通过它,我至少能够更新数据库中的记录。它与您目前的解决方案不同,它在Fill()之后将值应用于DataTable已执行。如果有记录需要更新,则必须在DataTable中手动搜索,这是缺点。 另一件事是,我意识到,如果您没有正确设置MissingSchemaAction,DataTable不会从数据库继承表模式

    下面是示例代码(完整的控制台应用程序):


    您当前的代码应该可以做到这一点。它是因错误而失败,还是以静默方式失败?这是ASP.NET吗?@Renan,它当前只是将值添加到上一个表的末尾。-是的,我可以在此处使用linqLook:,您需要至少指定用于更新数据的其他sql语句,包括where子句,通过它记录是唯一的已识别。@KaiHartmann不,您不需要:让我们很容易编程,但可能无法很好地扩展。如果没有太多记录,这应该可以正常工作。@MichaelTodd为真,但我相信截断/大容量复制组合应该适用于数十万条记录。但由于OP将所有数据都保存在内存数据选项卡中,因此它甚至不应该出现这种情况le和(希望)这应该不会太多。这是一个非常不雅观的、粗暴的解决方案。@YuriyGalanter Heh.+1,因为你的实用主义。@MichaelTodd-最多输入1500个。这个解决方案会成功吗:)
    CREATE TABLE [dbo].[ice_provinces](
        [pv_id] [int] IDENTITY(1,1) NOT NULL,
        [pv_name] [nvarchar](50) NOT NULL,
     CONSTRAINT [PK_ice_provinces] PRIMARY KEY CLUSTERED 
    (
        [pv_id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.SqlClient;
    using System.Data;
    
    namespace SQLCommandBuilder
    {
        class Program
        {
            static void Main(string[] args)
            {
                SqlConnectionStringBuilder ConnStringBuilder = new SqlConnectionStringBuilder();
                ConnStringBuilder.DataSource = @"(local)\SQLEXPRESS";
                ConnStringBuilder.InitialCatalog = "TestUndSpiel";
                ConnStringBuilder.IntegratedSecurity = true;
    
                SqlConnection sqlConn = new SqlConnection(ConnStringBuilder.ConnectionString);
    
                SqlDataAdapter adapter = new SqlDataAdapter(string.Format("SELECT * FROM {0}", "ice_provinces"), sqlConn);
                adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;   // needs to be set to apply table schema from db to datatable
    
                using (new SqlCommandBuilder(adapter))
                {
                    try
                    {
                        DataTable dtPrimary = new DataTable();                                   
    
                        adapter.Fill(dtPrimary);
    
                        // this would be a record you identified as to update:
                        dtPrimary.Rows[1]["pv_name"] = "value";
    
                        sqlConn.Open();
                        adapter.Update(dtPrimary);
                        sqlConn.Close();
                    }
                    catch (Exception es)
                    {
                        Console.WriteLine(es.Message);
                        Console.Read();
                    }
                }
            }
        }
    }