桌面应用程序部署 - 尝试写入只读数据库sqlite

4
我用C# VS2013和SQLite数据库创建了一个小型桌面应用程序进行数据插入操作,该应用程序使用了[WinForm]。它能正常工作并且能够执行所有的CRUD操作。但是当我使用Advance Installer创建安装程序时,每当我运行该应用程序并尝试插入数据时,就会弹出此窗口:

This is The Error I Got.

谢谢。

这是一些代码片段。

//Add Property Function.
string ConnectionString = "Data Source=database/MyProperty.db;Version=3;Read Only=False";

    public static long AddPropertyToDatabae( Property property )
    {
        SQLiteConnection con = new SQLiteConnection( ConnectionString );
        SQLiteCommand cmd = new SQLiteCommand
        {
            Connection = con,
            CommandText =
                "INSERT INTO Properties (PropertyName,PropertyAddress,PropertyCity,PropertyState,PropertyZip,PropertyNotes)" +
                " values (@Name,@Address,@City,@State,@Zip,@Notes)"
        };
        cmd.Parameters.AddWithValue( "@Name", property.PropertyName );
        cmd.Parameters.AddWithValue( "@Address", property.PropertyAddress );
        cmd.Parameters.AddWithValue( "@City", property.PropertyCity );
        cmd.Parameters.AddWithValue( "@State", property.PropertyState );
        cmd.Parameters.AddWithValue( "@Zip", property.PropertyZip );
        cmd.Parameters.AddWithValue( "@Notes", property.PropertyNotes );

        con.Open();
        cmd.ExecuteNonQuery();

        // Get the Last Inserted RowId.
        cmd.CommandText = "select last_insert_rowid()";
        long rowid = ( long )cmd.ExecuteScalar();

        con.Close();
        return rowid;
    }

注意

这段代码在VS中是百分之百可行的,但是当我创建应用程序的安装文件时就会出现错误。


在您的设置应用程序中,您是否执行了任何创建命令?如果这是一个现有的SqlLite文件,也许您尝试部署它的方式存在问题。能否向我们展示代码?同时,您能否逐步执行安装程序代码,以查找或重现错误? - MethodMan
不,我只使用INSERTSELECT命令。 - Awais
你在插入或选择命令方面肯定有所操作,能否展示一下这两个CRUD函数的代码? - MethodMan
我会在一分钟内向您展示... - Awais
你有什么解决方案吗?因为我尝试了许多不同的解决方案,但都没有起作用。 - Awais
显示剩余13条评论
4个回答

2
技术上说,错误不在SQLite数据库中。而是文件夹错误。我正在为数据库文件创建子文件夹,但它没有像本地输出文件夹一样的权限。所以我只是将我的数据库移动到主BIN文件夹中,它就起作用了。:-)
这是我找到解决方案的链接。 SQLite for Windows Runtime is returning an "ReadOnly" error SQLiteException object -- 重要 -- 如果你遇到这样的问题,请尝试将数据库文件的目录更改为主输出目录。

1
我曾经遇到过同样的基本问题,但是与其将数据库文件移动到不同的文件夹中,我也能通过以管理员身份运行试图写入数据库的可执行文件来解决这个问题。 - Joe Irby
@JoeIrby,你说得对。我后来找到了这个问题并且现在每次使用数据库时都会将exe文件以管理员身份运行,以便DB文件具有适当的读写权限。 - Awais
@Awais,你能提供新的连接字符串吗? - priyanka s
@priyankas 你可以做两件事,1:将应用程序设置为以管理员身份运行(管理员访问权限),然后您可以将您的数据库文件放在项目目录中的任何位置,它就可以完美地工作;2:只需将数据库文件放在 BIN 文件夹中,并使用以下连接字符串 " Data Source=YourDatabase.db;Version=3; "。 - Awais

1
在创建 Windows 安装程序设置文件时:设置应用程序文件夹路径为:[WindowsVolume][ProductName]。
我使用了 Advanced Installer 来创建 Windows 安装程序设置文件。

enter image description here

如果您尝试设置路径[ProgramFilesFolder][Manufacturer][ProductName],那么您将无法在Sqlite中写入数据,但是如果以管理员身份运行应用程序,则Sqlite只读问题将得到解决。

0
将你的Sql命令更改为以下命令,这样你就不必运行两个单独的Sql命令了。如果有两个人同时点击该代码并插入行,则不能保证您会得到正确的最后插入的行。我需要看一下安装程序代码,才能确定那里可能出现了什么问题。
"INSERT INTO Properties (PropertyName,PropertyAddress,PropertyCity,PropertyState,PropertyZip,PropertyNotes)" +
  " values (@Name,@Address,@City,@State,@Zip,@Notes)SELECT CAST(scope_identity() AS int)";
rowid = (int)cmd.ExecuteScalar();   

0

(可能有点晚了...)

我刚刚解决了这个问题。

一个应用程序可以任意读写它的LocalFolder,所以你只需要将你的数据文件复制到那个文件夹中。

代码如下:

StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("your-file-path"));
await file.CopyAsync(localFolder, "any name", NameCollisionOption.FailIfExists);

接下来你可以这样创建SQLiteConnection:

string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "abc.db");
SQLiteConnection connection = new SQLiteConnection($"Data Source={dbpath}")

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