2016-08-23 102 views
0

我在我的Xamarin.Forms应用程序中使用Sqlite.Net。到目前为止,它已经在返回对象的名单已经很大,如果我的目标是像这样一类:是否可以从Sqlite查询中返回动态对象或数据集?

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

现在我想从我的查询返回动态地DataSet相当于

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

现在从第二个查询中,我想返回一个DataSet而不是一个对象列表。我知道我可以创建一个新的对象,它将CustomersCalls的列组合起来,但我不想每次要查询数据库时都必须创建对象。

是否可以动态返回DatasetObject

+0

什么问题,你的问候返回'DataSet或DataTable'这是不是很困难的经历..提示做就.fill伪'()'方法谷歌搜索。有很多关于如何在stackoverflow上执行此操作的示例.. – MethodMan

+0

@MethodMan您确定我们正在讨论相同的Sqlite包装?我正在使用的'Sqlite.Net-PCL'上不存在'Fill'方法 – user1

回答

0

在我实际上设法想出将运行任何查询,并在列表项返回行的方法结束并将列作为数组中的对象:

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

SQLite.NET PCL是一个围绕sqlite的.NET包装。

因此,您可以通过在LINQ或Lambda中使用联接而不是在查询中查询类似于EF的查询。包装器将为您处理转换为sqlite查询。

然后,您可以返回连接类型或动态类型的新数据类型。

注意:连接不直接支持在sqlite(more info)和变通提到here

示例代码:

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版本:

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

你有这样的例子吗?我可以试试吗? – user1

+0

谢谢你的例子,但不幸的是它不起作用。你会得到一个'System.NotSupportedException:不支持连接。'是否有其他库或代码可以尝试? – user1

+1

多数民众赞成,这是有效的!如果我用'LINQ'完成相同的操作,我会更新答案 – user1

0

非常感谢你user1!作品完美。 这里仅仅是一个例子,如何使用乌尔法:

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

这听起来像你想要做的基本上是重新创建ADO.NET什么。当你说“DataSet”时,我猜你正在谈论ADO.NET。这可能意味着您不想使用内置于SQLite.Net库的ORM功能。

我已经创建了这个版本的库,允许你从SQLite数据库进行平表读取。这意味着如果您愿意,您可以将数据读入ADO.NET数据集。

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

相关问题