使用Microsoft.Data.Sqlite C#获取最后插入的行ID

3

我使用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;
    }
}
2个回答

6
你可以将这两个查询合并为一个单一的命令,不需要调用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的回答指出了这种解决方案的一些缺点。

2
这个简单一些,虽然我不得不将其转换为 long 而不是 int。谢谢。 - tronman

2
你最初的获取rowid的方法(通过分离插入和选择命令)更加合适和“安全”。当插入数据到你的表时(如果你有唯一索引),“合并INSERT和SELECT命令将忽略唯一约束违规”,你将只会得到“0”作为新的rowid,不会抛出异常!使用独立的命令会在无法正确插入数据到你的表中时导致SqliteExceptions。因此,我不会使用第二个“正确”的方法。最好使用你最初的代码——但对于INSERT使用ExecuteNonQuery,对于SELECT last_insert_rowid()使用ExecuteScalar。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接