【问题标题】:Get last insert rowid using Microsoft.Data.Sqlite C#使用 Microsoft.Data.Sqlite C# 获取最后一个插入 rowid
【发布时间】:2021-05-13 05:55:43
【问题描述】:

我使用 Microsoft.Data.Sqlite 库创建了一个带有 sqlite 数据库的 UWP 应用。插入新行后,我需要知道分配给新行的自动增量值。下面的代码使用了额外的查询“select last_insert_rowid()”,但是有没有更好的方法来获取这个值呢?

public static int AddMovie(Movie movie)
{
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, DB_FILENAME);
    using (SqliteConnection db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();

        SqliteCommand cmd = new SqliteCommand();
        cmd.Connection = db;

        cmd.CommandText = "INSERT INTO Movie VALUES (NULL, @Title, @Rating)";
        cmd.Parameters.AddWithValue("@Title", movie.Title);
        cmd.Parameters.AddWithValue("@Rating", movie.Rating);

        cmd.ExecuteReader();

        // Is there a better way to get this value?
        cmd = new SqliteCommand("SELECT last_insert_rowid()", db);
        SqliteDataReader query = cmd.ExecuteReader();

        var newId = 0;
        if (query.Read())
        {
            newId = query.GetInt32(0);
        }

        db.Close();

        return newId;
    }
}

【问题讨论】:

    标签: c# sqlite


    【解决方案1】:

    您可以将两个查询组合成一个命令,而不是调用cmd.ExecuteReader() 调用cmd.ExecuteScalar() 并将返回值转换为int

    public static long AddMovie(Movie movie)
    {
        string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, DB_FILENAME);
        using (SqliteConnection db = new SqliteConnection($"Filename={dbpath}"))
        {
            db.Open();
    
            SqliteCommand cmd = new SqliteCommand();
            cmd.Connection = db;
    
            cmd.CommandText = "INSERT INTO Movie VALUES (NULL, @Title, @Rating); SELECT last_insert_rowid();";
            cmd.Parameters.AddWithValue("@Title", movie.Title);
            cmd.Parameters.AddWithValue("@Rating", movie.Rating);
    
            return (long)cmd.ExecuteScalar();
        }
    }
    

    注意:Raycoon 的回答指出了此解决方案的一些缺点。

    【讨论】:

    • 这有点简单,尽管我必须转换为 long,而不是 int。谢谢。
    【解决方案2】:

    您检索 rowid 的初始方式(通过分隔插入和选择命令)更合适且更“安全”。 在表中插入数据时(如果您有唯一索引),结合使用 INSERT 和 SELECT 命令将忽略违反唯一约束。您将简单地获得“0”作为新的 rowid - 并且不会抛出异常!

    当数据无法正确插入表中时,使用单独的命令会导致 SqliteExceptions。因此,我不会使用第二种“正确”的方法。最好使用您的初始代码 - 但 ExecuteNonQuery 用于 INSERTExecuteScalar 用于 SELECT last_insert_rowid()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2023-03-16
      • 2011-04-30
      • 2011-06-30
      • 2011-06-01
      • 2011-02-25
      相关资源
      最近更新 更多