Typed queries disagree with CLR defaults for missing BSON fields
Typed queries and in-memory LINQ disagree when a persisted BSON field is absent and materialization supplies a CLR default. Track that concrete behavior separately from #2093, whose original model, predicate, sample document and exact version were never supplied. This reproduction does not establish the cause of that original report.
Reproduction
using System.Linq;
using LiteDB;
using var db = new LiteDatabase(":memory:");
db.GetCollection("users").Insert(new BsonDocument { ["_id"] = 41 });
var users = db.GetCollection<User>("users");
var inMemory = users.FindAll().Where(x => x.Removed == false)
.Select(x => x.Id).ToArray(); // [41]
var inDatabase = users.Find(x => x.Removed == false)
.Select(x => x.Id).ToArray(); // []
public class User
{
public int Id { get; set; }
public bool Removed { get; set; }
}The stored document lacks Removed. Materialization leaves it at false, while the BSON query compares an absent/null value against false and rejects it. Fully persisted controls match across both evaluation paths.
Preserved executable evidence
The original fixture is retained unchanged as LiteDB.Tests/Issues/Issue2093_Tests.cs. The historical filename is retained to preserve the frozen test identity and known-failure mappings; these tests now track this issue, not a confirmed reproduction of #2093.
The fixture independently seeds BSON, closes/reopens the database, verifies field absence and raw encodings, and checks renamed fields, enum string/integer storage, dates and an ID-query control. Latest sweep evidence: two missing-field cases fail; two fully persisted controls pass.
dotnet test LiteDB.Tests -c Release -f net8.0 -p:TestingEnabled=true \
--settings tests.runsettings --filter FullyQualifiedName~Issue2093_Design questions before implementation
- Decide whether typed queries should retain stored-BSON semantics or support explicitly configured defaults for absent fields. Do not silently redefine raw BSON queries.
- A CLR type default alone is insufficient:
public bool Removed { get; set; } = true;, constructors, custom factories and deserialization hooks can produce a different value. - Distinguish absent fields from explicitly stored null, false and true. Assess indexed/unindexed consistency and compatibility with existing queries and data.
- If opt-in defaults are chosen, define how they are configured and how queries/indexes interpret them; preserve controls for constructor-initialized values and existing documents.
This is separate design work, outside the current manual bug-fix sweep. The retained parity assertions demonstrate the mismatch; they do not settle the final compatibility contract.
Source: litedb-org/LiteDB