如何在Xamarin SQLite项目中使用泛型类

tkqqtvp1  于 2023-06-03  发布在  SQLite
关注(0)|答案(2)|浏览(281)

我正在开发一个在Xamarin中使用SQLite本地数据库的软件。我使用微软的Todo示例作为基础。
https://learn.microsoft.com/ja-jp/xamarin/xamarin-forms/data-cloud/data/databases
在此示例中,只存储Todo,因此访问SQLite的唯一类是TodoItemDatabase。在我们正在构建的软件中,我们计划访问多个表,如Todo、Memo、Diary等。在这种情况下,我们需要分别为它们创建TodoItemDatabase、MemoItemDatabase和DiaryItemDatabase。因此,我决定在这种情况下使用泛型类。

public class BaseDatabase<T>
    {
        static SQLiteAsyncConnection Database;

        public static readonly AsyncLazy<ItemDatabase> Instance = new AsyncLazy<ItemDatabase>(async () =>
        {
            File.Delete(Constants.DatabasePath);

            var instance = new ItemDatabase();
            try
            {
                CreateTableResult result = await Database.CreateTableAsync<T>();
            }
            catch(Exception exception)
            {
                var error = exception.Message;
            }
            return instance;
        });

        public BaseDatabase()
        {
            Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
        }

        public Task<List<T>> GetItemsAsync()
        {
            return Database.Table<T>().ToListAsync();
        }

        public Task<List<T>> GetItemsNotDoneAsync()
        {
            return Database.QueryAsync<T>("SELECT * FROM [Item] WHERE [Done] = 0");
        }

        public Task<T> GetItemAsync(string id)
        {
            return Database.Table<T>().Where(i => i.Id == id).FirstOrDefaultAsync();
        }

        public Task<int> SaveItemAsync(T item)
        {
            if (item.Id == null)
            {
                return Database.InsertAsync(item);
            }
            else
            {
                return Database.UpdateAsync(item);
            }
        }

        public Task<int> DeleteItemAsync(T item)
        {
            return Database.DeleteAsync(item);
        }
    }

但是,当我将Task替换为Taskand Task替换为Task作为BaseDatabase类以使其成为泛型类时,发生了两个错误。第一个是T必须是泛型类型或非抽象类型,其构造函数不带公共参数,才能在方法SQLiteAsyncConnection.Table()中用作参数T。T不包含Id定义,并且找不到接受类型T的第一个参数的可访问扩展方法ItemId。如何解决这两个问题?请告诉我如何在泛型类的代码中解决这两个问题。

px9o7tmv

px9o7tmv1#

“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“SQLiteAsyncConnection.CreateTableAsync(CreateFlags)”中的参数“T”
正如技巧中所提到的,在代码中,T必须是泛型类型或非抽象类型,具有不带公共参数的函数SQLiteAsyncConnection.CreateTableAsync的构造函数

CreateTableResult result = await Database.CreateTableAsync<T>();

因此,您需要使用一个公共类来替换此处的T
我们计划访问多个表,如Todo、Memo、Diary等。在这种情况下,我们需要分别为它们创建TodoItemDatabase、MemoItemDatabase和DiaryItemDatabase
在数据库中,您可以在其中创建许多表,而不是为每个表创建数据库。
总之,您可以在数据库中逐个创建表。
可以参考以下代码:

public class TodoItemDatabase
    {
        static SQLiteAsyncConnection Database;

        public static readonly AsyncLazy<TodoItemDatabase> Instance = new AsyncLazy<TodoItemDatabase>(async () =>
        {
            var instance = new TodoItemDatabase();
            CreateTableResult result = await Database.CreateTableAsync<TodoItem>();

            CreateTableResult result_memo = await Database.CreateTableAsync<Memo>();

            CreateTableResult result_diary = await Database.CreateTableAsync<Diary>();

            return instance;
        });

        public TodoItemDatabase()
        {
            Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
        }

        /*   query  funtion   */

        public Task<List<TodoItem>> GetItemsAsync()
        {
            return Database.Table<TodoItem>().ToListAsync();
        }

        public Task<List<Memo>> GetItemsAsync_memo()
        {
            return Database.Table<Memo>().ToListAsync();
        }
         // other code
}
q1qsirdb

q1qsirdb2#

这是一个有点旧,但不完全回答。我也遇到了这个问题,正在寻找如何解决这个问题,偶然发现了这篇文章,所以我把它放在这里:
“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“SQLiteAsyncConnection.CreateTableAsync(CreateFlags)”中的参数“T”
正如它所说的,它必须是非抽象的,并且有一个无参数的构造函数,要做到这一点,需要你的DatabaseService并将其添加到类定义中:

class BaseDatabase<T> where T : new()

这将允许您继续使用泛型类型。我还没有在我的场景中完全测试它,所以如果我指出了错误的地方,我道歉(如果我发现其他情况或其他限制,我会编辑)。
约束选项的源:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

相关问题