【问题标题】:SQLITE Delete item does't delete for realSQLITE 删除项目不会真正删除
【发布时间】:2021-06-09 23:44:06
【问题描述】:

我有一个 xamarin 表单应用程序,问题是当我从 sqlite 表中删除一个项目时,看起来一切正常,项目从集合中删除,网格更新等,但是当我重新启动应用程序,该项目仍然存在。就像删除只在内存中有效,但从未保存在数据库中。

我的代码在下面

我在我的 App 构造函数中创建了一个名为 DB 的实例

    public partial class App
    {
        static Database database;

        public static Database DB
        {
            get
            {
                if (database == null)
                {
                    string nombreBD = "MyDataBaseFile.db3";
                    string _databasePath = Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, nombreBD);
                    database = new Database(_databasePath);
                }
                return database;
            }
        }
................
}

我将 sqlite 与从类创建的表一起使用,就像这样

db = new SQLiteAsyncConnection(dbPath);
db.CreateTableAsync<MyType>().Wait();

其中 MyType 是这样的类

public class MyType
{   
        [PrimaryKey]
        public int Idtable { get; set; }

        ......
}

我尝试像这样删除表格的一行:

var x = await App.DB.GetItemAsync<MyType>(obj.Idtable );
int regsDeleted = await App.DB.DeleteItemAsync<MyType>(x);

GetItemsAsync 基本上是:await db.FindAsync&lt;T&gt;(id);

public async Task<T> GetItemAsync<T>(int id) where T : new()
    {
        try
        {
            return await db.FindAsync<T>(id);
        }
        catch (System.Exception ex)
        {
            throw new System.Exception($"Error sqlLite {MethodBase.GetCurrentMethod().Name}: {ex.Message}");
        }
    }

删除方法是这样的:

public async Task<int> DeleteItemAsync<T>(T item) where T : new()
{
    try
    {
        int regsDeleted=await db.DeleteAsync(item);
        db.GetConnection().Commit();
        return regsDeleted;
    }
    catch (System.Exception ex)
    {
        throw new System.Exception($"Error sqlLite {MethodBase.GetCurrentMethod().Name}: {ex.Message}");
    }
}

就像我说的那样,我没有任何错误,一切看起来都正常,但是当重新启动应用程序时,该项目仍然存在!
任何想法?也许要在连接中添加一些东西?交易?...任何帮助都会很棒

谢谢

更新经过大量测试我意识到问题不在于删除。问题是每次我通过 USB 电缆将应用程序从 VS 运行到我的 android 设备时,我不知道如何或为什么从某些备份中恢复数据库,我不知道何时何地完成。看起来Android有备份和我的应用程序的“数据”,当新版本到来时,他只是恢复数据。我读到 somne​​ 说 Xamarin.Essentials.FileSystem.AppDataDirectory 不应该用于保存数据库,所以问题是。保存 SQLLite 数据库的正确位置在哪里。有什么想法吗?我的应用程序没有部署空数据库,我的应用程序在第一次执行时创建了数据库。有谁知道如何避免文件夹的恢复?每次我从 VisualStudio 运行应用程序时?

【问题讨论】:

  • 我以前从未将Commit 与 sqlite 一起使用,如果删除它会怎样?您确定您的应用程序没有在启动时重新填充数据吗?如果你在 Delete 之后立即调用 GetItem,它仍然返回一个对象吗?
  • Example here,删除commit行,删除前检查db连接是否正确。
  • 我已经添加了提交,因为没有它,也不起作用,应用程序在启动时不会填充,即使它是真的,服务器中的数据也不再可用。我已经删除了所有表格,关闭了应用程序,但是当我启动时,所有数据都像魔术一样回来了。我无法在我的设备中找到 dataBase.db3 以在 Windows 文件资源管理器中手动删除它,也许是我创建 db 文件的方式?

标签: sqlite xamarin xamarin.forms android-sqlite


【解决方案1】:

DeleteAsync 可以在没有Commit 的情况下工作。我对您的代码进行了更改。它对我有用。

我添加了PrimaryKey 和AutoIncrement 属性以确保SQLite.NET 数据库中的每个Note 实例都将具有SQLite.NET 提供的唯一ID。

 public class MyType
{
    [PrimaryKey, AutoIncrement]
    public int Idtable { get; set; }
    public string Text { get; set; }

}

连接数据库、保存记录、删除行并获取所有项目的代码。

readonly string _databasePath = Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, "MyDataBaseFile.db3");

    SQLiteAsyncConnection database;
    public MyType myType { get; set; }
    int i = 0;

    public Page2()
    {
        InitializeComponent();
    }

    private void Connect_Clicked(object sender, EventArgs e)
    {
        database = new SQLiteAsyncConnection(_databasePath);
        database.CreateTableAsync<MyType>().Wait();
    }

    async void Save_Clicked(object sender, EventArgs e)
    {
        myType = new MyType() { Text = "Hello" + i };
        if (myType.Idtable != 0)
        {
            // Update an existing note.
            await database.UpdateAsync(myType);
            i++;
        }
        else
        {
            // Save a new note.
            await database.InsertAsync(myType);
            i++;
        }

    }

    async void Delete_Clicked(object sender, EventArgs e)
    {
        var x = await database.FindAsync<MyType>(myType.Idtable);
        int regsDeleted = await database.DeleteAsync(x);

    }

    async void Get_Clicked(object sender, EventArgs e)
    {
        var s = await database.Table<MyType>().ToListAsync();
         try
        {
            var s2 = await database.FindAsync<MyType>(myType.Idtable);
        }
        catch
        {
            return;
        }
    }
}

请注意,如果我重新启动应用程序,则没有 myType.Idtable。所以我使用 try catch 来运行我的项目。

为数据库添加四项并删除最后一项。

重启应用后,项目:

【讨论】:

  • 嗨,感谢您的代码,这真的很奇怪,我在 VS 中按 F5 测试应用程序并通过 USB 部署到我的三星,每次我执行调试部署操作时,数据库看起来很神奇,如果我运行部署的应用程序而不在 VS 中按 F5,只是从设备运行,......一切都按预期工作:(所以我猜 android 做了类似备份的事情,我不知道为什么每次 VS 部署android设备的app,操作系统恢复备份。这真的很奇怪!!
  • 我在这篇文章中读到了“这不是用于 Sqlite 数据库等的地方,如果你正在实施/遵守平台相关的规范”:stackoverflow.com/questions/51393561/…谈论使用“Xamarin.Essentials .FileSystem.AppDataDirectory”作为数据库的位置,...如果这不是正确的位置,它在哪里?因为在那个位置数据库会被隐藏,当您尝试通过 USB 从 Windows 资源管理器访问时
  • 据我所知,当您将数据库保存在路径中时,它仍然有效。您是否尝试在其他设备或模拟器上进行测试?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多