【问题标题】:SQLite Insert from Datatable从数据表插入 SQLite
【发布时间】:2019-04-17 06:06:03
【问题描述】:

使用下面的语句,查询的 @table 部分出现异常。可以这样使用数据表插入SQLite吗?

 DataTable table = new DataTable();
 table.Columns.Add("Path", typeof(string));
 table.Columns.Add("StopName", typeof(string));
 table.Columns.Add("Latitude", typeof(string));
 table.Columns.Add("Longitude", typeof(string));

 foreach (Result result in tempResults)
 {
      table.Rows.Add(result.Path, result.StopName, result.Latitude, result.Longitude);
 }

 SQLiteCommand command = new SQLiteCommand("INSERT OR REPLACE INTO ZZ_DBA_Stop (Path, StopName, Latitude, Longitude) SELECT Path, StopName, Latitude, Longitude FROM @table", connection) { CommandTimeout = 3600, CommandType = CommandType.Text };
 command.Parameters.AddWithValue("@table", table);
 await command.ExecuteNonQueryAsync();

【问题讨论】:

  • 否,FROM 参数中不能使用参数。无论如何,您不能传递 DataTable 并希望将其用于插入数据库表中。

标签: c# sqlite


【解决方案1】:

您不能将 DataTable 作为参数传递。 我认为你想使用 DataTable 作为参数的主要原因是你想在 sqlite 中批量插入。这是一个例子

using (var transaction = connection.BeginTransaction())
using (var command = connection.CreateCommand())
{
    command.CommandText =
        "INSERT INTO contact(name, email) " +
        "VALUES($name, $email);";

    var nameParameter = command.CreateParameter();
    nameParameter.ParameterName = "$name";
    command.Parameters.Add(nameParameter);

    var emailParameter = command.CreateParameter();
    emailParameter.ParameterName = "$email";
    command.Parameters.Add(emailParameter);

    foreach (var contact in contacts)
    {
        nameParameter.Value = contact.Name ?? DBNull.Value;
        emailParameter.Value = contact.Email ?? DBNull.Value;
        command.ExecuteNonQuery();
    }

    transaction.Commit();
}

Reference: Bulk Insert in Microsoft.Data.Sqlite

【讨论】:

    【解决方案2】:

    很遗憾,参数不能用于表示表或列的名称。您只能在 WHERE 语句或 UPDATE/INSERT/DELETE 操作中使用它们来表达值。

    所以你应该一个一个地插入你的记录,或者像this question中解释的那样编写代码来支持批量更新

    但是,如果您想试验一个非常有用的第三方库,您可以编写一个非常简单的代码。

    这个例子是使用 Dapper 完成的

    NuGet
    Project Site

    using(SQLiteConnection connection = GetOpenedConnection())
    {
        string cmdText = @"INSERT OR REPLACE INTO ZZ_DBA_Stop 
                          (Path, StopName, Latitude, Longitude) 
                          VALUES(@Path, @StopName, @Latitude, @Longitude) ";
        connection.ExecuteAsync(cmdText, tempResults);
    }
    

    Dapper 是一个简单的 ORM,它扩展了 IDbConnection 的功能。它知道如何处理您的模型并从数据库中存储和检索它们。
    在上面的示例中,您将整个列表作为第二个参数传递给 ExecuteAsync,Dapper 将为您插入整个列表中的数据。这里唯一的要求是您的模型的属性具有相同的字段名称

    GetOpenedConnection 只是返回已打开 SQLiteConnection 的方法的占位符。您可以将其替换为创建连接所需的代码,并在调用 ExecuteAsync 之前添加一个调用来打开

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多