Search code examples
c#sqlitexamarinsqlite.net

Is it possible to return dynamic objects or Dataset from a Sqlite Query?


I am using Sqlite.Net in my Xamarin.Forms application. So far it has been great at returning lists of objects if my object is a class like so:

SqliteDatabase.Connection.Query<Customer>("Select * from Customers");

I would now like to return the equivalent of a DataSet dynamically from my query

SqliteDatabase.Connection.Query("Select * from Customers inner join Calls on Customers.Id=Calls.CustomerId")

Now from the second query I would like to return a DataSet instead of a list of objects. I know I could create a new object which combines the columns of Customers and Calls but I don't want to have to create objects every time I want to query the database.

Is it possible to just dynamically return a Dataset or Object?


Solution

  • In the end I actually managed to come up with a method that will run any query and return the rows as items in the list and the columns as objects in the array:

        public List<object[]> RunSql(string sqlString, bool includeColumnNamesAsFirstRow)
        {
            var lstRes = new List<object[]>();
            SQLitePCL.sqlite3_stmt stQuery = null;
            try
            {
                stQuery = SQLite3.Prepare2(fieldStrikeDatabase.Connection.Handle, sqlString);
                var colLenght = SQLite3.ColumnCount(stQuery);
    
                if (includeColumnNamesAsFirstRow)
                {
                    var obj = new object[colLenght];
                    lstRes.Add(obj);
                    for (int i = 0; i < colLenght; i++)
                    {
                        obj[i] = SQLite3.ColumnName(stQuery, i);
                    }
                }
    
                while (SQLite3.Step(stQuery) == SQLite3.Result.Row)
                {
                    var obj = new object[colLenght];
                    lstRes.Add(obj);
                    for (int i = 0; i < colLenght; i++)
                    {
                         var columnType = SQLitePCL.raw.sqlite3_column_decltype(stQuery, i);
    
                         switch (columnType)
                         {
                             case "text":
                                  obj[i] = SQLite3.ColumnString(stQuery, i);
                                  break;
                             case "int":
                                   obj[i] = SQLite3.ColumnInt(stQuery, i);
                                   break;
                             case "real":
                                   obj[i] = SQLite3.ColumnDouble(stQuery, i);
                                   break;
                             case "blob":
                                   obj[i] = SQLite3.ColumnBlob(stQuery, i);
                                   break;
                             case "null":
                                   obj[i] = null;
                                   break;
                          }
                    }
                }
                return lstRes;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                if (stQuery != null)
                {
                    SQLite3.Finalize(stQuery); 
                }
            }
        }