5

我正在使用 SQLite-net ( https://github.com/praeclarum/sqlite-net ) 在 Android 上使用 Mono 实现数据库,并具有以下内容:

public class DatabaseTestASync
{
    private SQLiteAsyncConnection m_db;

    public delegate void StocksFound(List<Stock> list);
    public event StocksFound StocksFoundListener;

    // Uninteresting parts remove, e.g. constructor

    public void AddStock(Stock stock)
    {
        m_db.InsertAsync(stock).ContinueWith(t => { Debug.WriteLine(stock.Symbol + " added"); });
    }

    public void GetAllStocks()
    {
        AsyncTableQuery<Stock> query = m_db.Table<Stock>().Where(stock => true);
        query.ToListAsync().ContinueWith(QueryReturns);
    }

    private void QueryReturns(Task<List<Stock>> t)
    {
        if (StocksFoundListener != null)
            StocksFoundListener(t.Result);
    }

这非常适合给我一个股票列表,但我设想在我的项目中有一组表,并且不想为每个表创建单独的 AddX、GetAllX、QueryReturns(X) 等。我正在采用一种通用的方式来执行这些数据库操作,并尝试了以下方法:

public class DBQuery<T>
{
    private SQLiteAsyncConnection m_db;
    public delegate void OnRecordsFound(List<T> list);
    public event OnRecordsFound RecordsFoundListener;

    public DBQuery (SQLiteAsyncConnection db)
    {
        m_db = db;
    }

    public void GetAllRecords()
    {
        AsyncTableQuery<T> query = m_db.Table<T>().Where(r => true); // COMPILE ERROR HERE
        query.ToListAsync().ContinueWith(QueryReturns);
    }

    private void QueryReturns(Task<List<T>> t)
    {
        if (RecordsFoundListener != null)
            RecordsFoundListener(t.Result);
    }
}

但是,它不会编译为:“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“DatabaseUtility.AsyncTableQuery”中的参数“T”。

关于如何让这种通用数据库访问工作的任何想法?

4

1 回答 1

7

我真的不知道 SQLite 内部结构,但这完全是关于generics......

因为AsyncTableQuery是这样定义的

public class AsyncTableQuery<T>
        where T : new ()
    {

...或者只是基于您的错误,您需要对您的T:

public class DBQuery<T> where T : new ()

如果您使用的类或方法具有constrained generic parameter- 您需要对您的方法(或类,取决于T定义的位置)执行相同的操作。

于 2013-04-25T02:16:40.420 回答