简体   繁体   English

SQLite.net 表查询抛出 NullReferenceException

[英]SQLite.net table query throws NullReferenceException

I'm using the following line of code to query some data from a given table in a SQLite database (platform is WP81 but I guess this doesn't matter here).我正在使用以下代码行从 SQLite 数据库中的给定表中查询一些数据(平台是 WP81,但我想这在这里无关紧要)。

return await Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to).ToListAsync().ConfigureAwait(false);

When I execute my code I get a NullReferenceException in the Where clause.当我执行我的代码时,我在 Where 子句中得到一个 NullReferenceException。 When I remove the where condition everything works fine.当我删除 where 条件时,一切正常。

return await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);

In order to make sure that all entries in my table are valid and there is no null value in the Date column I used an SQL tool to look into the SQLite database.为了确保我的表中的所有条目都有效并且日期列中没有空值,我使用 SQL 工具查看 SQLite 数据库。

As I can't debug lambda expressions I'm kind of stuck on how to find the issue here.由于我无法调试 lambda 表达式,因此我有点困惑如何在这里找到问题。 My assumption is that something goes wrong due to the async handling.我的假设是由于异步处理出现问题。

Edit: Here is the exact stacktrace of the exception编辑:这是异常的确切堆栈跟踪

{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)}

Edit 2:编辑2:

I played around a bit more and figured out the following.我玩了更多,想出了以下内容。

var query = Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to);
return query.ToListAsync().ConfigureAwait(false);

When executing this statement it actually breaks in the ToListAsync() method instead of the Where method.执行此语句时,它实际上中断了 ToListAsync() 方法而不是 Where 方法。 However, this doesn't help either.然而,这也无济于事。

Later I tried the following which actually works.后来我尝试了以下实际有效的方法。

var result = await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);
return result.Where(wd => wd.Date >= @from && wd.Date <= to).ToList();

So what I did is to separate the Where method actually.所以我所做的实际上是将 Where 方法分开。 But although this works for me it does not answer my question because I'm still wondering why this does not work.但是,尽管这对我有用,但它并没有回答我的问题,因为我仍然想知道为什么这不起作用。

I'm pretty sure you are not working in this project anymore, but I'm going to answer it because it may help someone which still is struggling with this problem.我很确定你不再在这个项目中工作了,但我会回答它,因为它可能会帮助仍然在这个问题上挣扎的人。

The problem is your entity and I don't know what exactly is the problem because you didn't post your class here.问题出在您的实体上,我不知道到底是什么问题,因为您没有在这里发布您的课程。 But basically you probably were trying to access a property that wasn't fetch from your database yet.但基本上,您可能正在尝试访问尚未从数据库中获取的属性。 For example, I have a class with two properties:例如,我有一个具有两个属性的类:

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
}

I don't know why SQLite does that, but when it is querying your entities, if in your query you're filtering by IsLate property, it's going to crash because Date property wasn't fetch yet.我不知道为什么 SQLite 会这样做,但是当它查询您的实体时,如果您在查询中按IsLate属性进行过滤,它会崩溃,因为尚未获取Date属性。

For solving this you'll have to fetch the entities first, then filter by this property.为了解决这个问题,您必须先获取实体,然后按此属性进行过滤。 That's basically what you did in EDIT 2 .这基本上就是你在EDIT 2 中所做的。 You've fetch all entities then filtered.您已获取所有实体,然后进行过滤。

Maybe I am too new to know what I am talking about, but I think your last example just needed an await statement before your ToListAsync call.也许我太新,不知道我在说什么,但我认为你的最后一个例子只需要在你的ToListAsync调用之前使用await语句。

var query = Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to);
return await query.ToListAsync().ConfigureAwait(false);

Not sure on the specifics of the first problem, but I would think that it has something to do with the TableAsyncQuery object, that the Where statement produces, not being fully initialized before the ToListAsync calls it on another thread.不确定第一个问题的细节,但我认为它与 TableAsyncQuery 对象有关,Where 语句生成,在 ToListAsync 在另一个线程上调用它之前没有完全初始化。

adding bit more details to Daniel Cunha answer i have this in my cProduct class向 Daniel Cunha 的回答添加更多细节,我的 cProduct 类中有这个

    [PrimaryKey, AutoIncrement]
    public int rowid
    {
        get => _rowid;
        set => _rowid = value;
    }

    [Ignore]
    public int ID => rowid; // just for convinience

this query works product.Product = dbConnection.Table<cProduct>().Where(s => s.rowid == product.ProductID).FirstOrDefault();此查询有效product.Product = dbConnection.Table<cProduct>().Where(s => s.rowid == product.ProductID).FirstOrDefault();

but this fails with null reference exception但这因空引用异常而失败

product.Product = dbConnection.Table<cProduct>().Where(s => s.ID == product.ProductID).FirstOrDefault();

s.ID can't be use in db query.. there is not such field in the table. s.ID 不能在 db 查询中使用.. 表中没有这样的字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM