我正在用sqlite-net做WP8。有时我希望在没有定义表模型的情况下进行原始查询。
我所做的是在下面进行查询,并尝试获取其属性:
string query = "SELECT firstname, lastname FROM users";
var records = db.Query<object>(query).ToList();
foreach (var r in records)
{
System.Diagnostics.Debug.WriteLine(r.GetType().GetProperty("firstname").GetValue(r,null).toString());
}
但是,&#34; System.NullReferenceException&#34;发生的情况。
我可以知道如何在不声明表模型的情况下实际获得该值吗?
答案 0 :(得分:1)
简单地说:
string query = "SELECT firstname, lastname FROM users";
Statement stQuery = SQLite3.Prepare2(connection.Handle, query);
while ((SQLite3.Result result = SQLite3.Step(stQuery)) == SQLite3.Result.Row)
{
//your stuff here
}
SQLite3.Finalize(stQuery);
答案 1 :(得分:1)
你可以用这种方式扩展分部类:
namespace SQLite
{
public partial class SQLiteConnection
{
public List<object[]> CustomQuery(string query, params object[] args)
{
var cmd = CreateCommand(query, args);
return cmd.ExecuteCustomQuery();
}
}
public partial class SQLiteCommand
{
public List<object[]> ExecuteCustomQuery()
{
if (SQLiteConnection.Trace)
{
Debug.WriteLine("Executing Query: " + this);
}
var stmt = Prepare();
try
{
var colLenght = SQLite3.ColumnCount(stmt);
var lstRes = new List<object[]>();
while (SQLite3.Step(stmt) == SQLite3.Result.Row)
{
var obj = new object[colLenght];
lstRes.Add(obj);
for (int i = 0; i < colLenght; i++)
{
var colType = SQLite3.ColumnType(stmt, i);
switch (colType)
{
case SQLite3.ColType.Blob:
obj[i] = SQLite3.ColumnBlob(stmt, i);
break;
case SQLite3.ColType.Float:
obj[i] = SQLite3.ColumnDouble(stmt, i);
break;
case SQLite3.ColType.Integer:
obj[i] = SQLite3.ColumnInt(stmt, i);
break;
case SQLite3.ColType.Null:
obj[i] = null;
break;
case SQLite3.ColType.Text:
obj[i] = SQLite3.ColumnString(stmt, i);
break;
}
}
}
return lstRes;
}
finally
{
SQLite3.Finalize(stmt);
}
}
}
}
并且在你有一个方法返回一个你可以用这种方式调用的对象数组列表之后:
var query = "select c.Id, c.Name, (select count(*) from Products where IdCategory = c.Id) from Categories c order by c.Name";
var lst = this.SqlConn.CustomQuery(query);
return (from s in lst
select new CategoryDescriptor {
Id = (int) s[0],
Name = (string) s[1],
ProductsCount = (int) s[2]
});
答案 2 :(得分:1)
使用前两个答案(第一个答案需要更改源代码,第二个答案不完整)
我想出了这个方法:
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);
}
}
}