SQLite.Net-PCL奇怪的选择行为
本文关键字:选择 Net-PCL SQLite | 更新日期: 2023-09-27 18:29:36
使用任何NuGet包:SQLite.Net-PCL-Win32平台、SQLite.Net-PCL-XamarIOS平台或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等我们不感兴趣的数据的情况下,这是不好的。
这种行为是故意的还是我遗漏了什么?
我使用POD类解决了这个问题,该类包含我通过SQLIteConnection.Query("Some SQL Query")方法查询的离散字段。其中T将是包含感兴趣字段的特定POD。只要字段名称与SELECT之后列出的字段匹配,就可以映射它们。
我仍然认为这还不够理想,因为我们不想创建一堆类来表示每个查询结果。我们可能可以对匿名类型做一些事情,但在运行时可能会很混乱,而且成本高昂。
不管是否找到记录,它都可能返回结果(映射的对象),因为Entity类中的字段是非引用类型,所以它们取默认值。在我的应用程序中,我选择记录的方式有点不同,也许我做错了(性能方面),但从未遇到过类似的问题。基本上,我的查询看起来像
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
}
}