我正在开发一个在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。如何解决这两个问题?请告诉我如何在泛型类的代码中解决这两个问题。
2条答案
按热度按时间px9o7tmv1#
“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“SQLiteAsyncConnection.CreateTableAsync(CreateFlags)”中的参数“T”
正如技巧中所提到的,在代码中,T必须是泛型类型或非抽象类型,具有不带公共参数的函数
SQLiteAsyncConnection.CreateTableAsync
的构造函数因此,您需要使用一个公共类来替换此处的
T
。我们计划访问多个表,如Todo、Memo、Diary等。在这种情况下,我们需要分别为它们创建TodoItemDatabase、MemoItemDatabase和DiaryItemDatabase
在数据库中,您可以在其中创建许多表,而不是为每个表创建数据库。
总之,您可以在数据库中逐个创建表。
可以参考以下代码:
q1qsirdb2#
这是一个有点旧,但不完全回答。我也遇到了这个问题,正在寻找如何解决这个问题,偶然发现了这篇文章,所以我把它放在这里:
“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“SQLiteAsyncConnection.CreateTableAsync(CreateFlags)”中的参数“T”
正如它所说的,它必须是非抽象的,并且有一个无参数的构造函数,要做到这一点,需要你的DatabaseService并将其添加到类定义中:
这将允许您继续使用泛型类型。我还没有在我的场景中完全测试它,所以如果我指出了错误的地方,我道歉(如果我发现其他情况或其他限制,我会编辑)。
约束选项的源:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters