Summary
The persisted author/series metadata cache never returned a hit on SQLite, so every author and series page re-fetched the full catalog from Audible on each load. The cache-read query ordered by Nullable<DateTime>.GetValueOrDefault(...), which the SQLite EF Core provider can't translate — the query throws, each caller's best-effort catch swallows it as a cache miss, and the cache is effectively dead. This switches the ordering to a translatable COALESCE (??) and adds regression coverage that runs against the real SQLite provider.
Changes
Fixed
- The four catalog-cache reads in
AudiobookRepository(GetCachedAuthorByNameAsync,GetCachedAuthorByAsinAsync,GetCachedSeriesByNameAsync,GetCachedSeriesByAsinAsync) now order byentry.LastFetchedAt ?? entry.UpdatedAt(maps to SQLCOALESCE) instead ofLastFetchedAt.GetValueOrDefault(UpdatedAt), which the SQLite EF provider cannot translate and throws on at execution time. Identical freshest-first ordering, but it no longer throws — so the author/series cache actually returns hits instead of re-fetching from Audible on every page load. An inline comment at each site records why, to prevent the pattern regressing.
Testing
- New
AudiobookRepository_CatalogCacheReadTestsexercises the four reads against the real SQLite provider (Microsoft.Data.Sqlite:memory:) rather than the EF InMemory provider, which tolerates the untranslatable LINQ and so cannot reproduce the failure. The tests fail on the pre-fix code withTranslation of method 'System.DateTime?.GetValueOrDefault' failedand pass with the fix. - Full suite green:
dotnet test(1015/1015).
Notes
- No changes to the cache write paths or schema — behavior is identical apart from the cache now actually being read.
- Rebased onto current
canary; theCHANGELOG.mdentry was removed per review (the project no longer tracksCHANGELOG.md).
Automated Canary build