[英]SQLite.net table query throws NullReferenceException
我正在使用以下代碼行從 SQLite 數據庫中的給定表中查詢一些數據(平台是 WP81,但我想這在這里無關緊要)。
return await Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to).ToListAsync().ConfigureAwait(false);
當我執行我的代碼時,我在 Where 子句中得到一個 NullReferenceException。 當我刪除 where 條件時,一切正常。
return await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);
為了確保我的表中的所有條目都有效並且日期列中沒有空值,我使用 SQL 工具查看 SQLite 數據庫。
由於我無法調試 lambda 表達式,因此我有點困惑如何在這里找到問題。 我的假設是由於異步處理出現問題。
編輯:這是異常的確切堆棧跟蹤
{System.NullReferenceException: Object reference not set to an instance of an object.
at SQLite.Net.TableQuery`1.CompileExpr(Expression expr, List`1 queryArgs)
at SQLite.Net.TableQuery`1.CompileExpr(Expression expr, List`1 queryArgs)
at SQLite.Net.TableQuery`1.CompileExpr(Expression expr, List`1 queryArgs)
at SQLite.Net.TableQuery`1.GenerateCommand(String selectionList)
at SQLite.Net.TableQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at SQLite.Net.Async.AsyncTableQuery`1.<ToListAsync>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at TimeStamp.Core.Services.DataService.<GetWorkDays>d__c.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TimeStamp.Core.ViewModel.MainViewModel.<LoadWorkDays>d__1a.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)}
編輯2:
我玩了更多,想出了以下內容。
var query = Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to);
return query.ToListAsync().ConfigureAwait(false);
執行此語句時,它實際上中斷了 ToListAsync() 方法而不是 Where 方法。 然而,這也無濟於事。
后來我嘗試了以下實際有效的方法。
var result = await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);
return result.Where(wd => wd.Date >= @from && wd.Date <= to).ToList();
所以我所做的實際上是將 Where 方法分開。 但是,盡管這對我有用,但它並沒有回答我的問題,因為我仍然想知道為什么這不起作用。
我很確定你不再在這個項目中工作了,但我會回答它,因為它可能會幫助仍然在這個問題上掙扎的人。
問題出在您的實體上,我不知道到底是什么問題,因為您沒有在這里發布您的課程。 但基本上,您可能正在嘗試訪問尚未從數據庫中獲取的屬性。 例如,我有一個具有兩個屬性的類:
public class MyClass
{
public DateTime Date { get; set; } // You're saving this property in the database
public bool IsLate => Date < DateTime.Today; // This property is not be saving, and probably is the cause of your exception
}
我不知道為什么 SQLite 會這樣做,但是當它查詢您的實體時,如果您在查詢中按IsLate屬性進行過濾,它會崩潰,因為尚未獲取Date屬性。
為了解決這個問題,您必須先獲取實體,然后按此屬性進行過濾。 這基本上就是你在EDIT 2 中所做的。 您已獲取所有實體,然后進行過濾。
也許我太新,不知道我在說什么,但我認為你的最后一個例子只需要在你的ToListAsync
調用之前使用await
語句。
var query = Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to);
return await query.ToListAsync().ConfigureAwait(false);
不確定第一個問題的細節,但我認為它與 TableAsyncQuery 對象有關,Where 語句生成,在 ToListAsync 在另一個線程上調用它之前沒有完全初始化。
向 Daniel Cunha 的回答添加更多細節,我的 cProduct 類中有這個
[PrimaryKey, AutoIncrement]
public int rowid
{
get => _rowid;
set => _rowid = value;
}
[Ignore]
public int ID => rowid; // just for convinience
此查詢有效product.Product = dbConnection.Table<cProduct>().Where(s => s.rowid == product.ProductID).FirstOrDefault();
但這因空引用異常而失敗
product.Product = dbConnection.Table<cProduct>().Where(s => s.ID == product.ProductID).FirstOrDefault();
s.ID 不能在 db 查詢中使用.. 表中沒有這樣的字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.