Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating generic queries in SQLite-net C# using SQLiteAsyncConnection

I'm using SQLite-net (https://github.com/praeclarum/sqlite-net) for implementing a database using Mono on Android and have the following:

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);
    }

This is great for giving me a list of stocks, but I envisage having a collection of tables in my project and don't want to create a separate AddX, GetAllX, QueryReturns(X), etc. for each table. I'm after a generic way of doing these database operations and tried the following:

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);
    }
}

However, it doesn't compile saying: 'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'DatabaseUtility.AsyncTableQuery'.

Any ideas about how I can get this kind of generic database access working?

like image 617
Dave W Avatar asked Apr 24 '13 15:04

Dave W


1 Answers

I don't really know the SQLite internals, but this is strictly about generics...

Since AsyncTableQuery is defined like this

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

...or just based on your error, you need to put the same constraint on your T:

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

If you're using a class or a method which has a constrained generic parameter - you need to do the same on your method (or a class, depending on where the T is defined).

like image 52
NSGaga-mostly-inactive Avatar answered Nov 05 '22 05:11

NSGaga-mostly-inactive