使用任何NuGet包:SQLite.Net-PCL - Win32平台,SQLite.Net-PCL - XamarinIOS平台或SQLite.Net-PCL XamarinAndroid平台我一般都遇到选择问题。特别是每当我从LINQ或原始SQL中的数据库中选择时,我都会回到看似包含默认值的对象。
这是一个示例控制台应用程序来演示我的问题:
using System;
using System.Linq;
using SQLite.Net;
using SQLite.Net.Platform.Win32;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Open a connection to the database
using (var database = new SQLiteConnection(new SQLitePlatformWin32(), "db.db"))
{
// Create a simple table
database.CreateTable<Entity>();
// Add a simple record to it each time we start the application
database.Insert(new Entity { Data = Guid.NewGuid().ToString(), BoolData = true, IntData = 5 });
Console.WriteLine("---------> Inserted item:");
// Display all our records
foreach (var e in database.Table<Entity>())
{
Console.WriteLine(e);
}
Console.WriteLine(Environment.NewLine);
Console.WriteLine("---------> Linq select Ids:");
// For every record we'll select the Id field - this is not working
foreach (var e in database.Table<Entity>().Select(e => e.Id))
{
Console.WriteLine(e);
}
Console.WriteLine(Environment.NewLine);
Console.WriteLine("---------> Id by scalar query:");
// Let's try going after a value explicitly - this is fine
var r1 = database.ExecuteScalar<int>("SELECT Id FROM Entity WHERE Id == 1");
Console.WriteLine(r1);
Console.WriteLine(Environment.NewLine);
Console.WriteLine("---------> Ids by query:");
// So lets try going after our Id field from a query - this still dosen't work
foreach (var e in database.Query<int>("SELECT Id FROM Entity"))
{
Console.WriteLine(e);
}
Console.WriteLine(Environment.NewLine);
Console.WriteLine("---------> Linq select Ids after force to memory:");
// Now lets try forcing a where to execute before performing the select - this works but it's bad
foreach (var e in database.Table<Entity>().Where(e => e.IntData == 5).ToList().Select(e => e.Id))
{
Console.WriteLine(e);
}
Console.ReadKey();
}
}
}
}
实体只是一个简单的POD:
using SQLite.Net.Attributes;
namespace ConsoleApplication1
{
public class Entity
{
public Entity() { }
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Data { get; set; }
public int IntData { get; set; }
public bool BoolData { get; set; }
public override string ToString()
{
return string.Format("Id: {0}, Data: {1}, IntData: {2}, BoolData: {3}", Id, Data, IntData, BoolData);
}
}
}
所以我能够让它工作的唯一方法就是先将内存强制放入内存中......在我们可能拥有包含BLOB等的数据的情况下,这是不好的,我们对此不感兴趣。
这种行为是故意还是我错过了什么?
答案 0 :(得分:0)
嗯它可能返回结果(你的映射对象),无论是否找到记录,或者因为实体类中的字段是非引用类型,它们都采用默认值。在我的应用程序中,我以不同的方式选择记录,也许我做错了(表现明智)但从未遇到过类似的问题。基本上我的查询看起来像
int id = GetID();
using(var connection = Db.getConnection())
{
var result = connection.Table<Entity>().where(x=> x.id == id).firsOrDefault();
if(result != null)
{
//record found
}
else
{
//not found
}
}
答案 1 :(得分:0)
我通过使用包含我通过SQLIteConnection.Query(“Some SQL query”)方法查询的离散字段的POD类来解决这个问题。其中T是包含感兴趣的字段的特定POD。只要字段名称与SELECT之后列出的字段匹配,就可以映射它们。
我仍然认为这仍然不太理想,因为我们不想创建一堆类来表示每个查询结果。我们可能会对Anonymous Types做些什么,但在运行时可能会很麻烦且费用昂贵。