8

次のコード行を使用して、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);

テーブルのすべてのエントリが有効で、Date 列に null 値がないことを確認するために、SQL ツールを使用して SQLite データベースを調べました。

ラムダ式をデバッグできないので、ここで問題を見つける方法に行き詰まっています。私の仮定は、非同期処理が原因で何かがうまくいかないということです。

編集: 例外の正確なスタックトレースは次のとおりです

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

このステートメントを実行すると、実際には Where メソッドではなく ToListAsync() メソッドで中断されます。ただし、これも役に立ちません。

後で、実際に機能する次のことを試しました。

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

だから私がしたことは、実際に Where メソッドを分離することです。しかし、これは私にとってはうまくいきますが、なぜこれがうまくいかないのか疑問に思っているので、私の質問には答えません。

4

3 に答える 3

1

私が何を話しているのか分からないかもしれませんが、あなたの最後の例は、awaitあなたの電話の前に声明が必要だったと思いますToListAsync.

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

最初の問題の詳細はわかりませんが、ToListAsync が別のスレッドでそれを呼び出す前に完全に初期化されていない、Where ステートメントが生成する TableAsyncQuery オブジェクトと関係があると思います。

于 2015-01-05T22:23:08.437 に答える