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

社会主义新天地 提交于 2019-11-26 21:44:43

问题


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?


回答1:


SQLite.NET PCL is a .NET wrapper around sqlite.

Therefore you can query similar to EF by using a join in in LINQ or Lambda than in the Query. The wrapper will handle the conversion to sqlite query for you.

You can then return a new datatype of the joined type or a dynamic type.

Note : Joins are not directly supported in sqlite (more info) and work around is mentioned here.

Sample Code :

var conn = new SQLiteConnection(sqlitePlatform, "foofoo");
var query = from customer in conn.Table<Customers>().ToList()
            join call in conn.Table<Calls>().ToList()
                         on customer.ID equals call.CustomerId                
            select new { Customer = customer , Calls = call };

Lambda version:

conn.Table<Customer>().ToList().Join
(conn.Table<Call>().ToList(),
customer => customer.Id,
call => call.CustomerId, 
(customer, call) => new { Customer = customer, Calls = call });



回答2:


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 colType = SQLite3.ColumnType(stQuery, i);
                    switch (colType)
                    {
                        case SQLite3.ColType.Blob:
                            obj[i] = SQLite3.ColumnBlob(stQuery, i);
                            break;
                        case SQLite3.ColType.Float:
                            obj[i] = SQLite3.ColumnDouble(stQuery, i);
                            break;
                        case SQLite3.ColType.Integer:
                            obj[i] = SQLite3.ColumnInt(stQuery, i);
                            break;
                        case SQLite3.ColType.Null:
                            obj[i] = null;
                            break;
                        case SQLite3.ColType.Text:
                            obj[i] = SQLite3.ColumnString(stQuery, i);
                            break;
                    }
                }
            }
            return lstRes;
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            if (stQuery != null)
            {
                SQLite3.Finalize(stQuery); 
            }
        }
    }



回答3:


thank u so much user1! works perfect. here is just an example how to use ur method:

var objects = mySQLiteConnection.RunSql("SELECT * FROM Persons", true);

// ColumnNames
List<string> ColumnNames = new List<string>();
for (int column = 0; column < objects[0].Length; column++)
{
    if (objects[0][column] != null) spaltennamen.Add((string)objects[0][column]);
}

// RowValues
for (int row = 1; row < objects.Count; row++)
{
    for (int column = 0; column < objects[row].Length; column++)
    {
        if (objects[row][column] != null) System.Diagnostics.Debug.WriteLine(spaltennamen[column] + " : " + objects[row][column]);
    }
}



回答4:


It sounds like what you want to do is essentially recreate ADO.NET. When you say "DataSet", I'm guessing that you are talking about ADO.NET. This probably means that you don't want to use the ORM functionality built in to the SQLite.Net library.

I have created this version of the library that will allow you to do flat table reads from an SQLite database. It means that you CAN read the data in to an ADO.NET dataset if you like.

https://github.com/MelbourneDeveloper/SQLite.Net.Standard



来源:https://stackoverflow.com/questions/39106298/is-it-possible-to-return-dynamic-objects-or-dataset-from-a-sqlite-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!