Korzystam z poniższego wiersza kodu, aby wysłać zapytanie do niektórych danych z danej tabeli w bazie danych SQLite (platforma to WP81, ale myślę, że to nie ma znaczenia).Zapytanie tabeli SQLite.net zgłasza NullReferenceException
return await Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to).ToListAsync().ConfigureAwait(false);
Kiedy wykonać mój kod otrzymuję NullReferenceException w klauzuli WHERE. Kiedy usuwam warunek, gdzie wszystko działa poprawnie.
return await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);
W celu upewnienia się, że wszystkie wpisy w moim stole są ważne i nie ma wartość null w kolumnie Data użyłem narzędzia SQL zajrzeć do bazy danych SQLite.
Ponieważ nie mogę debugować wyrażeń lambda, utknąłem na tym, jak znaleźć problem tutaj. Zakładam, że coś poszło nie tak z powodu obsługi asynchronicznej.
Edit: Oto dokładny StackTrace wyjątku
{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:
Grałem około trochę więcej i zorientowali się, co następuje.
var query = Connection.Table<WorkDay>().Where(wd => wd.Date >= @from && wd.Date <= to);
return query.ToListAsync().ConfigureAwait(false);
Podczas wykonywania tej instrukcji faktycznie włamuje się do metody ToListAsync() zamiast metody Where. Jednak to też nie pomaga.
Później próbowałem następujących, które faktycznie działa.
var result = await Connection.Table<WorkDay>().ToListAsync().ConfigureAwait(false);
return result.Where(wd => wd.Date >= @from && wd.Date <= to).ToList();
Więc to, co zrobiłem, to oddzielenie metody Where w rzeczywistości. Ale chociaż to działa dla mnie, to nie odpowiada na moje pytanie, ponieważ wciąż zastanawiam się, dlaczego to nie działa.
Co masz na myśli przez "NRE w klauzuli where"? Jeśli faktycznie kompiluje się w drzewo wyrażeń i jest przetwarzane jako takie, nie powinno być możliwe, aby sama lambda wyrzuciła wyjątek, a jedynie kod, który je przetwarza. Czy rzeczywiście otrzymujesz wyjątek przed wywołaniem "ToListAsync", czy też masz na myśli "jeśli usunę Gdzie, nie ma wyjątku"? –
Czy zdefiniowano zmienne "od" i "do"? Widzę też, że 'to' tutaj nie ma' @ '. i czy masz null 'Date's w' WorkDay'? – MPelletier
@ MPelletier Tak. Sprawdziłem przy użyciu debuggera, który zarówno od i do mieć wartość. from ma znak @, ponieważ jest również słowem kluczowym w języku C# i dlatego zazwyczaj nie można używać zmiennej o tej nazwie. – Stephan