Conversation
Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
…e placeholders Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add SqlExpression attribute for SQL templates
Add linq2db-style Mar 14, 2026
[SqlExpression] attribute for custom SQL translation in EF Core queries
Copilot stopped work on behalf of
PhenX due to an error
March 14, 2026 22:18
…n property Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
Copilot
AI
changed the title
Add linq2db-style
Add provider-specific SQL expressions via Mar 14, 2026
[SqlExpression] attribute for custom SQL translation in EF Core queriesConfiguration on SqlExpressionAttribute
…, and StringSyntax hint for SqlExpression Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
Copilot
AI
changed the title
Add provider-specific SQL expressions via
SqlExpression: extension methods, STRFTIME/mixed-literal templates, EFP0003 compile-time analyzer, StringSyntax
Mar 14, 2026
Configuration on SqlExpressionAttribute
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.
Extends
[SqlExpression]with four improvements: extension method support verified with tests, correct translation of templates containing SQL literal fragments (e.g.STRFTIME('%Y', {0})), a compile-time Roslyn analyzer that catches out-of-range{N}argument indices, and[StringSyntax("sql")]for IDE awareness.Template translator — mixed literal/placeholder args
Previously only
FUNCNAME({0}, {1})(pure placeholder args) was supported. A newSplitArgumentshelper splits argument lists while respecting single-quoted strings and nested parentheses; literal tokens becomeFragment(...)expressions:Extension methods
[SqlExpression]works on extension methods —{0}maps to thethisparameter exactly as it does for regular static parameters. AddedSqlExtensionFunctionshelper class and three new functional tests (SQL Server + SQLite) confirming both direct and extension-syntax call forms translate correctly.EFP0003Roslyn analyzerSqlExpressionAnalyzerreports a compile-time error when any{N}index in a SQL template exceeds the method's parameter count:Covers multiple stacked attributes, extension methods, and methods with no parameters. Added 9 unit tests in
SqlExpressionAnalyzerTests.[StringSyntax("sql")]Applied to the
sqlconstructor parameter ofSqlExpressionAttributefor IDE SQL-awareness and future tooling hooks.Original prompt
Add EF Core Custom SQL Expression Support (linq2db-style)
This task is to implement the 3 first features that bring linq2db-style fine-grained SQL translation control to this EF Core library (
EntityFrameworkCore.Projectables), which already supports projecting over properties and functions in LINQ queries.The goal is to allow users to annotate C# methods with SQL expression templates (similar to linq2db's
[Sql.Expression]) and have EF Core translate them correctly during query execution.Task 1:
[SqlExpression]AttributeCreate a custom attribute
SqlExpressionAttributethat allows decorating static methods with a SQL template string.Requirements:
{0},{1}, etc.ServerSideOnlyboolean property (default:true) — if true, the method cannot be evaluated client-side and must throwNotImplementedExceptionin its bodyTask 2: Detection and Translation via
IMethodCallTranslatorImplement an
IMethodCallTranslator(and the requiredIMethodCallTranslatorPlugin) that:[SqlExpression]is used in a LINQ queryISqlExpressionFactoryto build the appropriateSqlExpressionby substituting the positional arguments into the template using aSqlFragmentExpressionor equivalentnullfor methods not decorated with[SqlExpression]Registration:
DbContextOptionsBuilder, e.g.:Or, if it integrates into the existing Projectables infrastructure, hook it into the existing setup method.
Task 3: Integration Tests
Add integration/unit tests that verify end-to-end translation:
[SqlExpression("UPPER({0})")]in a LINQ.Where()clause and verifies the generated SQL containsUPPER(...)[SqlExpression("COALESCE({0}, {1})")]in a.Select()and verifies correct SQL outputNotes
The following is the prior conversation context from the user's chat exploration (may be truncated):
User: What has linq2db that ef core does not?
Assistant: Here's a breakdown of features that linq2db has which EF Core lacks or handles less well:
🚀 Features linq2db Has That EF Core Does Not
1. Native Bulk Operations
EFCore.BulkExtensions) to achieve similar results.2. Fine-Grained SQL Translation Control
3. Schema-Free / DTO Mapping
DbSet<T>or modifying the context.4. No Tracking by Default
.AsNoTracking().5. Wider Database Provider Support
6. Table-Valued Parameters (TVPs)
7. Stored Procedure & Table Function Mapping
8. External / XML Mapping Schemas
This pull request was created from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.