feat: net8.0 target, MemoryExtensions.Contains support in SQL translator#76
Open
korchak-aleksandr wants to merge 11 commits intomainfrom
Open
feat: net8.0 target, MemoryExtensions.Contains support in SQL translator#76korchak-aleksandr wants to merge 11 commits intomainfrom
korchak-aleksandr wants to merge 11 commits intomainfrom
Conversation
- TargetFramework: netstandard2.0 → net8.0 - LangVersion: latest → 12 - PackageVersion: 10.7.2 → 10.8.0 - Microsoft.Data.SqlClient: 5.1.0 → 6.1.4 - Removed BCL packages: System.Reflection.Emit, System.Runtime, System.Runtime.Extensions, System.ComponentModel.Annotations, System.Security.Permissions - SecurityUtils: removed CAS (ReflectionPermission) — no-op on .NET 5+ - SYSLIB0011 (BinaryFormatter): suppressed — legacy DB serialization path - Tests: updated to net8.0, suppressed CS0169 QueryConverter: support MemoryExtensions.Contains from .NET 10 In .NET 10, array.Contains(value) in expression trees compiles to MemoryExtensions.Contains(ReadOnlySpan<T>.op_Implicit(array), value) instead of Enumerable.Contains(array, value). Added handling to translate it to SQL IN clause the same way. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…fix CI - Add Directory.Build.props: TargetFramework=net8.0, LangVersion=12 - Add Directory.Packages.props: centralized package versions - Restore original SecurityUtils.cs (add System.Security.Permissions 8.0.0 package; suppress SYSLIB0003 — CAS is a no-op on .NET 5+, types still compile with the compat package) - Simplify csproj files: remove properties now in Directory.Build.props - Update pull-request.yml: setup-dotnet@v4, dotnet-version 8.0.x
- Microsoft.NET.Test.Sdk: 17.4.1 → 18.3.0 - MSTest.TestAdapter/TestFramework: 3.0.2 → 3.11.1 - Moq: 4.18.4 → 4.20.72
Tests verify that array.Contains(value) in LINQ queries translates to SQL IN clause on both net8.0 and net10.0. On .NET 10, the compiler generates MemoryExtensions.Contains — the fix in QueryConverter ensures it produces identical SQL to Enumerable.Contains on .NET 8. Also update CI to install both .NET 8 and .NET 10 SDKs.
- Add <TargetFramework /> to clear Directory.Build.props default - Set AppendTargetFrameworkToOutputPath=true to avoid DLL overwrites
efimovvo
reviewed
Mar 23, 2026
More robust: matches any conversion to ReadOnlySpan<T>, not just the specific op_Implicit generated by the current C# compiler.
…ork per project - Directory.Build.props: LangVersion, Company, Authors, Copyright, PackageLicenseExpression - Each csproj now declares its own TargetFramework/TargetFrameworks - Remove duplicate Company/Authors/Copyright from individual csproj files - Remove leftover Product/NeutralLanguage from test csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Main fix:
MemoryExtensions.Containssupport inQueryConverterIn .NET 10,
array.Contains(value)in LINQ expression trees compiles toMemoryExtensions.Contains(ReadOnlySpan<T>.op_Implicit(array), value)instead ofEnumerable.Contains(array, value). This causedNotSupportedExceptionwhen LINQ-to-SQL tried to translate such queries.Added handling in
QueryConverter.VisitMethodCallto recognize this pattern and translate it to a SQLINclause — the same wayEnumerable.Containsis handled:The check matches any conversion to
ReadOnlySpan<T>by return type rather than by method name (op_Implicit), making it robust against future compiler changes.Infrastructure
Directory.Build.props:TargetFramework=net8.0,LangVersion=12Directory.Packages.props: centralized package versionsREADME.mdPackage updates
TargetFrameworknetstandard2.0net8.0PackageVersion10.7.210.8.0Microsoft.Data.SqlClient5.1.06.1.4Mindbox.Expressions3.3.03.3.1Microsoft.NET.Test.Sdk17.4.118.3.0MSTest.TestAdapter/Framework3.0.23.11.1Moq4.18.44.20.72System.Reflection.Emit,System.Runtime,System.Runtime.ExtensionsSystem.Security.Permissionskept (required forSecurityUtils.cs);SYSLIB0003andSYSLIB0011suppressed — CAS is a no-op on .NET 5+ andBinaryFormatteris a legacy path.Tests
net8.0;net10.0— same suite runs on both runtimesArrayContainsTranslationTestswith two cases:ArrayContains_TranslatesToSqlIn— verifiesWHERE Id IN (@p0, @p1, @p2)on both .NET 8 and .NET 10ArrayContains_EmptyArray_TranslatesToFalse— verifiesWHERE 0 = 1Test plan
dotnet build— 0 errors, 0 warningsdotnet test— 62 passed, 17 skipped, 0 failed (net8.0 + net10.0)