2014-09-30 85 views
7

我正在使用下面的代码行来查询SQLite数据库中的给定表中的一些数据(平台是WP81,但我想这在这里没关系)。SQLite.net表查询抛出NullReferenceException

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方法实际分开。但是,尽管这对我有用,但它并不回答我的问题,因为我仍然在想为什么这样做不起作用。

+0

你是什么意思的“NRE在where子句”?如果它实际上是编译到表达式树中并进行处理,那么lambda本身不应抛出异常,只能处理它。在“ToListAsync”被调用之前,你是否真的获得了一个异常?或者你是否意指“如果我删除Where,那么没有例外”? – 2014-09-30 22:46:33

+0

是否定义了“from”和“to”变量?我也看到'to'这里没有'@'。你在'WorkDay'中有'Date'吗? – MPelletier 2014-09-30 23:01:20

+0

@MPelletier是的。我使用调试器进行了检查,这两者都来自并具有价值。 from拥有@因为它也是C#中的关键字,因此通常不允许使用具有该名称的变量。 – Stephan 2014-10-01 15:02:57

回答

1

也许我太新了,不知道我在说什么,但我认为你的最后一个例子只需要你的ToListAsync调用之前的await声明。

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

对第一个问题的具体情况不知道,但我认为它有事情做与TableAsyncQuery对象,即Where语句产生的,没有被完全初始化的ToListAsync调用它在另一个线程之前。

+0

不幸的是,我现在不能再测试了,因为我现在正在使用另一个数据库而不是SQLite(iBoxDB)。但我敢肯定,Visual Studio会抱怨,如果我尝试访问任务结果与异步那里。但我可能错了。 – Stephan 2015-01-05 22:59:50

相关问题