Version
Summary
On .NET 10 the common pattern
var ids = new[] { 1 };
var result = col.Find(x => ids.Contains(x.Id));
can fail because the compiler sometimes chooses the span-based overload. The captured array is implicitly converted to ReadOnlySpan and the expression tree contains an op_Implicit(...) node. LiteDB's LINQ-to-Bson translator does not currently handle that shape and throws when trying to translate the lambda.
Why this happens
The C# overload resolution rules changed: arrays can implicitly convert to ReadOnlySpan and the compiler may pick MemoryExtensions.Contains(ReadOnlySpan, T) over Enumerable.Contains(IEnumerable, T).
See: https://learn.microsoft.com/dotnet/core/compatibility/core-libraries/10.0/csharp-overload-resolution
Workaround
Convert to an IEnumerable explicitly:
var ids = new[] { 1 }.AsEnumerable();
var result = col.Find(x => ids.Contains(x.Id));
Expected behavior
The same code should translate to the same BsonExpression on .NET 9 and .NET 10 (e.g. @0 ANY = @1).
Proposed fix
Add a MemoryExtensionsResolver mapping MemoryExtensions.Contains -> @0 ANY = @1 (optionally also IndexOf, StartsWith, EndsWith).
In the LINQ expression visitor, narrowly unwrap op_Implicit conversions only when the conversion is using types of the following group ReadOnlySpan / Span / ReadOnlyMemory / Memory.
Use reflection checks with hardcoded type name comparisons so no project multitargeting is required.
Version
Summary
On .NET 10 the common pattern
can fail because the compiler sometimes chooses the span-based overload. The captured array is implicitly converted to ReadOnlySpan and the expression tree contains an op_Implicit(...) node. LiteDB's LINQ-to-Bson translator does not currently handle that shape and throws when trying to translate the lambda.
Why this happens
The C# overload resolution rules changed: arrays can implicitly convert to ReadOnlySpan and the compiler may pick MemoryExtensions.Contains(ReadOnlySpan, T) over Enumerable.Contains(IEnumerable, T).
See: https://learn.microsoft.com/dotnet/core/compatibility/core-libraries/10.0/csharp-overload-resolution
Workaround
Convert to an IEnumerable explicitly:
Expected behavior
The same code should translate to the same BsonExpression on .NET 9 and .NET 10 (e.g. @0 ANY = @1).
Proposed fix
Add a MemoryExtensionsResolver mapping MemoryExtensions.Contains -> @0 ANY = @1 (optionally also IndexOf, StartsWith, EndsWith).
In the LINQ expression visitor, narrowly unwrap op_Implicit conversions only when the conversion is using types of the following group ReadOnlySpan / Span / ReadOnlyMemory / Memory.
Use reflection checks with hardcoded type name comparisons so no project multitargeting is required.