【问题标题】:How to use generic class in Xamarin SQLite Project如何在 Xamarin SQLite 项目中使用泛型类
【发布时间】:2022-01-14 16:39:58
【问题描述】:

我正在开发一个在 Xamarin 中使用 SQLite 本地数据库的软件。 我使用 Microsoft 的 Todo 示例作为基础。

https://docs.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 替换为 Task 并将 Task 替换为 Task 作为类 BaseDatabase 以使其成为泛型类时,发生了两个错误。 第一个是 T 必须是泛型类型或非抽象类型,其构造函数没有公共参数,可用作 SQLiteAsyncConnection.Table() 方法中的参数 T。 T 不包含 Id 定义,并且找不到接受 T 类型的第一个参数的可访问扩展方法 ItemId。 如何解决这两个问题? 请让我知道如何在泛型类的代码中解决这两个问题。

【问题讨论】:

    标签: c# sqlite xamarin generics


    【解决方案1】:

    'T' 必须是具有公共无参数的非抽象类型 构造函数,以便将其用作泛型类型中的参数“T”或 方法'SQLiteAsyncConnection.CreateTableAsync(CreateFlags)

    正如提示所提到的,在您的代码中,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
    }
    

    【讨论】:

    • 感谢您的回答。我知道如何制作桌子。我有个问题。 GetItemAsync/GetItemAsnc_memo 代码几乎相同且相互重复。有什么方法可以使用 T、泛型或其他方法对它们进行标准化?
    • 可以创建一个父类,让其他表类扩展这个父类。并且可以在使用时进行类型转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    • 2017-02-02
    • 2021-09-21
    • 1970-01-01
    • 2020-04-19
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多