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等我们不感兴趣的数据的情况下,这是不好的。

这种行为是故意的还是我遗漏了什么?

SQLite.Net-PCL奇怪的选择行为

我使用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
    }
}