Skip to content

Switch Expressions

Switch expressions are one of the most useful C# features that ExpressiveSharp enables in expression trees. They are translated to nested ternary expressions at compile time, which LINQ providers map to their native conditional forms (SQL CASE, MongoDB $switch, etc.).

Basic Syntax

Mark any property or method with [Expressive] and use a switch expression in the body:

db
    .Products
    .Select(p => new { p.Name, Tier = p.GetTier() })

// Setup
public static class ProductExt
{
    [Expressive]
    public static string GetTier(this Product p) => p.ListPrice switch
    {
        >= 100m => "Premium",
        >= 50m  => "Standard",
        _       => "Budget",
    };
}
SELECT "p"."Name", CASE
    WHEN ef_compare("p"."ListPrice", '100.0') >= 0 THEN 'Premium'
    WHEN ef_compare("p"."ListPrice", '50.0') >= 0 THEN 'Standard'
    ELSE 'Budget'
END AS "Tier"
FROM "Products" AS "p"
SELECT p."Name", CASE
    WHEN p."ListPrice" >= 100.0 THEN 'Premium'
    WHEN p."ListPrice" >= 50.0 THEN 'Standard'
    ELSE 'Budget'
END AS "Tier"
FROM "Products" AS p
SELECT [p].[Name], CASE
    WHEN [p].[ListPrice] >= 100.0 THEN N'Premium'
    WHEN [p].[ListPrice] >= 50.0 THEN N'Standard'
    ELSE N'Budget'
END AS [Tier]
FROM [Products] AS [p]
playground.products.Aggregate([
    {
         "$project" : {
             "Name" : "$Name",
            "Tier" : {
                 "$cond" : {
                     "if" : {
                         "$gte" : [
                            "$ListPrice",
                            { "$numberDecimal" : "100" }
                        ] 
                    },
                    "then" : "Premium",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$gte" : [
                                    "$ListPrice",
                                    { "$numberDecimal" : "50" }
                                ] 
                            },
                            "then" : "Standard",
                            "else" : "Budget" 
                        } 
                    } 
                } 
            },
            "_id" : 0 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.GetTier_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt 
    {
        // [Expressive]
        // public static string GetTier(this Product p) => p.ListPrice switch
        // {
        //     >= 100m => "Premium",
        //     >= 50m => "Standard",
        //     _ => "Budget",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>> GetTier_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression() 
        {
            var p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product), "p");
            var expr_0 = global::System.Linq.Expressions.Expression.Property(p_p, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product).GetProperty("ListPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.ListPrice
            var expr_1 = global::System.Linq.Expressions.Expression.Constant("Budget", typeof(string)); // "Budget"
            var expr_3 = global::System.Linq.Expressions.Expression.Constant(50m, typeof(decimal)); // 50m
            var expr_2 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_3);
            var expr_4 = global::System.Linq.Expressions.Expression.Constant("Standard", typeof(string)); // "Standard"
            var expr_5 = global::System.Linq.Expressions.Expression.Condition(expr_2, expr_4, expr_1, typeof(string));
            var expr_7 = global::System.Linq.Expressions.Expression.Constant(100m, typeof(decimal)); // 100m
            var expr_6 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_7);
            var expr_8 = global::System.Linq.Expressions.Expression.Constant("Premium", typeof(string)); // "Premium"
            var expr_9 = global::System.Linq.Expressions.Expression.Condition(expr_6, expr_8, expr_5, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>>(expr_9, p_p);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetTier", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_ProductExt", "GetTier_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "Zf1WsQ4zpjQmQBqqXbg1NoEBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_23<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: p => new { p.Name, Tier = p.GetTier() }
            var i3e6114c23_p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "p");
            var i3e6114c23_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c23_p_p, typeof(T0).GetProperty("Name", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.Name
            var i3e6114c23_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetTier", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c23_p_p }); // p.GetTier()
            var i3e6114c23_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c23_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c23_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c23_expr_1, i3e6114c23_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Name"), typeof(T1).GetProperty("Tier") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c23_expr_0, i3e6114c23_p_p);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

The source generator produces a chain of conditional expressions that each provider renders in its own dialect (see the tabs above).

Relational Patterns

Relational operators (<, <=, >, >=) work in switch arms:

db
    .Products
    .Select(p => new { p.Name, Category = p.PriceCategory() })

// Setup
public static class ProductExt
{
    [Expressive]
    public static string PriceCategory(this Product p) => p.ListPrice switch
    {
        < 10m   => "Cheap",
        < 50m   => "Moderate",
        < 100m  => "Expensive",
        >= 100m => "Premium",
    };
}
SELECT "p"."Name", CASE
    WHEN ef_compare("p"."ListPrice", '10.0') < 0 THEN 'Cheap'
    WHEN ef_compare("p"."ListPrice", '50.0') < 0 THEN 'Moderate'
    WHEN ef_compare("p"."ListPrice", '100.0') < 0 THEN 'Expensive'
    WHEN ef_compare("p"."ListPrice", '100.0') >= 0 THEN 'Premium'
END AS "Category"
FROM "Products" AS "p"
SELECT p."Name", CASE
    WHEN p."ListPrice" < 10.0 THEN 'Cheap'
    WHEN p."ListPrice" < 50.0 THEN 'Moderate'
    WHEN p."ListPrice" < 100.0 THEN 'Expensive'
    WHEN p."ListPrice" >= 100.0 THEN 'Premium'
END AS "Category"
FROM "Products" AS p
SELECT [p].[Name], CASE
    WHEN [p].[ListPrice] < 10.0 THEN N'Cheap'
    WHEN [p].[ListPrice] < 50.0 THEN N'Moderate'
    WHEN [p].[ListPrice] < 100.0 THEN N'Expensive'
    WHEN [p].[ListPrice] >= 100.0 THEN N'Premium'
END AS [Category]
FROM [Products] AS [p]
playground.products.Aggregate([
    {
         "$project" : {
             "Name" : "$Name",
            "Category" : {
                 "$cond" : {
                     "if" : {
                         "$lt" : [
                            "$ListPrice",
                            { "$numberDecimal" : "10" }
                        ] 
                    },
                    "then" : "Cheap",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$lt" : [
                                    "$ListPrice",
                                    { "$numberDecimal" : "50" }
                                ] 
                            },
                            "then" : "Moderate",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$lt" : [
                                            "$ListPrice",
                                            { "$numberDecimal" : "100" }
                                        ] 
                                    },
                                    "then" : "Expensive",
                                    "else" : {
                                         "$cond" : {
                                             "if" : {
                                                 "$gte" : [
                                                    "$ListPrice",
                                                    { "$numberDecimal" : "100" }
                                                ] 
                                            },
                                            "then" : "Premium",
                                            "else" : null 
                                        } 
                                    } 
                                } 
                            } 
                        } 
                    } 
                } 
            },
            "_id" : 0 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.PriceCategory_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt 
    {
        // [Expressive]
        // public static string PriceCategory(this Product p) => p.ListPrice switch
        // {
        //     < 10m => "Cheap",
        //     < 50m => "Moderate",
        //     < 100m => "Expensive",
        //     >= 100m => "Premium",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>> PriceCategory_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression() 
        {
            var p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product), "p");
            var expr_0 = global::System.Linq.Expressions.Expression.Property(p_p, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product).GetProperty("ListPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.ListPrice
            var expr_1 = global::System.Linq.Expressions.Expression.Default(typeof(string));
            var expr_3 = global::System.Linq.Expressions.Expression.Constant(100m, typeof(decimal)); // 100m
            var expr_2 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_3);
            var expr_4 = global::System.Linq.Expressions.Expression.Constant("Premium", typeof(string)); // "Premium"
            var expr_5 = global::System.Linq.Expressions.Expression.Condition(expr_2, expr_4, expr_1, typeof(string));
            var expr_7 = global::System.Linq.Expressions.Expression.Constant(100m, typeof(decimal)); // 100m
            var expr_6 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_0, expr_7);
            var expr_8 = global::System.Linq.Expressions.Expression.Constant("Expensive", typeof(string)); // "Expensive"
            var expr_9 = global::System.Linq.Expressions.Expression.Condition(expr_6, expr_8, expr_5, typeof(string));
            var expr_11 = global::System.Linq.Expressions.Expression.Constant(50m, typeof(decimal)); // 50m
            var expr_10 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_0, expr_11);
            var expr_12 = global::System.Linq.Expressions.Expression.Constant("Moderate", typeof(string)); // "Moderate"
            var expr_13 = global::System.Linq.Expressions.Expression.Condition(expr_10, expr_12, expr_9, typeof(string));
            var expr_15 = global::System.Linq.Expressions.Expression.Constant(10m, typeof(decimal)); // 10m
            var expr_14 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_0, expr_15);
            var expr_16 = global::System.Linq.Expressions.Expression.Constant("Cheap", typeof(string)); // "Cheap"
            var expr_17 = global::System.Linq.Expressions.Expression.Condition(expr_14, expr_16, expr_13, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>>(expr_17, p_p);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("PriceCategory", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_ProductExt", "PriceCategory_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "W6QtYdNhhdDnCroKTIgoFoEBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_23<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: p => new { p.Name, Category = p.PriceCategory() }
            var i3e6114c23_p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "p");
            var i3e6114c23_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c23_p_p, typeof(T0).GetProperty("Name", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.Name
            var i3e6114c23_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("PriceCategory", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c23_p_p }); // p.PriceCategory()
            var i3e6114c23_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c23_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c23_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c23_expr_1, i3e6114c23_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Name"), typeof(T1).GetProperty("Category") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c23_expr_0, i3e6114c23_p_p);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

WARNING

Without a discard arm (_), the generated expression has no fallback. If no arm matches at runtime, a SwitchExpressionException would be thrown in C#. In SQL, the result is NULL (the ELSE clause is omitted). Always include a discard arm for safety.

and / or Combinators

Combine patterns with and and or for range checks and alternatives:

db
    .Products
    .Select(p => new { p.Name, Band = p.GetBand() })

// Setup
public static class ProductExt
{
    [Expressive]
    public static string GetBand(this Product p) => p.StockQuantity switch
    {
        >= 90 and <= 100 => "Excellent",
        >= 70 and < 90   => "Good",
        >= 50 and < 70   => "Average",
        _                => "Poor",
    };
}
SELECT "p"."Name", CASE
    WHEN "p"."StockQuantity" >= 90 AND "p"."StockQuantity" <= 100 THEN 'Excellent'
    WHEN "p"."StockQuantity" >= 70 AND "p"."StockQuantity" < 90 THEN 'Good'
    WHEN "p"."StockQuantity" >= 50 AND "p"."StockQuantity" < 70 THEN 'Average'
    ELSE 'Poor'
END AS "Band"
FROM "Products" AS "p"
SELECT p."Name", CASE
    WHEN p."StockQuantity" >= 90 AND p."StockQuantity" <= 100 THEN 'Excellent'
    WHEN p."StockQuantity" >= 70 AND p."StockQuantity" < 90 THEN 'Good'
    WHEN p."StockQuantity" >= 50 AND p."StockQuantity" < 70 THEN 'Average'
    ELSE 'Poor'
END AS "Band"
FROM "Products" AS p
SELECT [p].[Name], CASE
    WHEN [p].[StockQuantity] >= 90 AND [p].[StockQuantity] <= 100 THEN N'Excellent'
    WHEN [p].[StockQuantity] >= 70 AND [p].[StockQuantity] < 90 THEN N'Good'
    WHEN [p].[StockQuantity] >= 50 AND [p].[StockQuantity] < 70 THEN N'Average'
    ELSE N'Poor'
END AS [Band]
FROM [Products] AS [p]
playground.products.Aggregate([
    {
         "$project" : {
             "Name" : "$Name",
            "Band" : {
                 "$cond" : {
                     "if" : {
                         "$and" : [
                            {
                                 "$gte" : ["$StockQuantity", 90] 
                            },
                            {
                                 "$lte" : ["$StockQuantity", 100] 
                            }
                        ] 
                    },
                    "then" : "Excellent",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$and" : [
                                    {
                                         "$gte" : ["$StockQuantity", 70] 
                                    },
                                    {
                                         "$lt" : ["$StockQuantity", 90] 
                                    }
                                ] 
                            },
                            "then" : "Good",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$and" : [
                                            {
                                                 "$gte" : ["$StockQuantity", 50] 
                                            },
                                            {
                                                 "$lt" : ["$StockQuantity", 70] 
                                            }
                                        ] 
                                    },
                                    "then" : "Average",
                                    "else" : "Poor" 
                                } 
                            } 
                        } 
                    } 
                } 
            },
            "_id" : 0 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.GetBand_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt 
    {
        // [Expressive]
        // public static string GetBand(this Product p) => p.StockQuantity switch
        // {
        //     >= 90 and <= 100 => "Excellent",
        //     >= 70 and < 90 => "Good",
        //     >= 50 and < 70 => "Average",
        //     _ => "Poor",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>> GetBand_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression() 
        {
            var p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product), "p");
            var expr_0 = global::System.Linq.Expressions.Expression.Property(p_p, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product).GetProperty("StockQuantity", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.StockQuantity
            var expr_1 = global::System.Linq.Expressions.Expression.Constant("Poor", typeof(string)); // "Poor"
            var expr_4 = global::System.Linq.Expressions.Expression.Constant(50, typeof(int)); // 50
            var expr_3 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_4);
            var expr_6 = global::System.Linq.Expressions.Expression.Constant(70, typeof(int)); // 70
            var expr_5 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_0, expr_6);
            var expr_2 = global::System.Linq.Expressions.Expression.AndAlso(expr_3, expr_5);
            var expr_7 = global::System.Linq.Expressions.Expression.Constant("Average", typeof(string)); // "Average"
            var expr_8 = global::System.Linq.Expressions.Expression.Condition(expr_2, expr_7, expr_1, typeof(string));
            var expr_11 = global::System.Linq.Expressions.Expression.Constant(70, typeof(int)); // 70
            var expr_10 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_11);
            var expr_13 = global::System.Linq.Expressions.Expression.Constant(90, typeof(int)); // 90
            var expr_12 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_0, expr_13);
            var expr_9 = global::System.Linq.Expressions.Expression.AndAlso(expr_10, expr_12);
            var expr_14 = global::System.Linq.Expressions.Expression.Constant("Good", typeof(string)); // "Good"
            var expr_15 = global::System.Linq.Expressions.Expression.Condition(expr_9, expr_14, expr_8, typeof(string));
            var expr_18 = global::System.Linq.Expressions.Expression.Constant(90, typeof(int)); // 90
            var expr_17 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_0, expr_18);
            var expr_20 = global::System.Linq.Expressions.Expression.Constant(100, typeof(int)); // 100
            var expr_19 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThanOrEqual, expr_0, expr_20);
            var expr_16 = global::System.Linq.Expressions.Expression.AndAlso(expr_17, expr_19);
            var expr_21 = global::System.Linq.Expressions.Expression.Constant("Excellent", typeof(string)); // "Excellent"
            var expr_22 = global::System.Linq.Expressions.Expression.Condition(expr_16, expr_21, expr_15, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>>(expr_22, p_p);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetBand", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_ProductExt", "GetBand_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "jD4/2uc49GK8Y/nMOohyDYEBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_23<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: p => new { p.Name, Band = p.GetBand() }
            var i3e6114c23_p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "p");
            var i3e6114c23_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c23_p_p, typeof(T0).GetProperty("Name", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.Name
            var i3e6114c23_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetBand", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c23_p_p }); // p.GetBand()
            var i3e6114c23_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c23_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c23_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c23_expr_1, i3e6114c23_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Name"), typeof(T1).GetProperty("Band") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c23_expr_0, i3e6114c23_p_p);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

Using or for alternative values:

db
    .Orders
    .Select(o => new { o.Id, Type = o.GetDayType() })

// Setup
public static class OrderExt
{
    [Expressive]
    public static string GetDayType(this Order o) => (int)o.PlacedAt.DayOfWeek switch
    {
        0 or 6 => "Weekend",
        _      => "Weekday",
    };
}
SELECT "o"."Id", CASE
    WHEN CAST(strftime('%w', "o"."PlacedAt") AS INTEGER) = 0 OR CAST(strftime('%w', "o"."PlacedAt") AS INTEGER) = 6 THEN 'Weekend'
    ELSE 'Weekday'
END AS "Type"
FROM "Orders" AS "o"
SELECT o."Id", CASE
    WHEN floor(date_part('dow', o."PlacedAt"))::int = 0 OR floor(date_part('dow', o."PlacedAt"))::int = 6 THEN 'Weekend'
    ELSE 'Weekday'
END AS "Type"
FROM "Orders" AS o
SELECT [o].[Id], [o].[PlacedAt]
FROM [Orders] AS [o]
playground.orders.Aggregate([
    {
         "$project" : {
             "_id" : "$_id",
            "Type" : {
                 "$cond" : {
                     "if" : {
                         "$or" : [
                            {
                                 "$eq" : [
                                    {
                                         "$subtract" : [
                                            { "$dayOfWeek" : "$PlacedAt" },
                                            1
                                        ] 
                                    },
                                    0
                                ] 
                            },
                            {
                                 "$eq" : [
                                    {
                                         "$subtract" : [
                                            { "$dayOfWeek" : "$PlacedAt" },
                                            1
                                        ] 
                                    },
                                    6
                                ] 
                            }
                        ] 
                    },
                    "then" : "Weekend",
                    "else" : "Weekday" 
                } 
            } 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_OrderExt.GetDayType_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_OrderExt 
    {
        // [Expressive]
        // public static string GetDayType(this Order o) => (int)o.PlacedAt.DayOfWeek switch
        // {
        //     0 or 6 => "Weekend",
        //     _ => "Weekday",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order, string>> GetDayType_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order_Expression() 
        {
            var p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order), "o");
            var expr_2 = global::System.Linq.Expressions.Expression.Property(p_o, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order).GetProperty("PlacedAt", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // o.PlacedAt
            var expr_1 = global::System.Linq.Expressions.Expression.Property(expr_2, typeof(global::System.DateTime).GetProperty("DayOfWeek", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance));
            var expr_0 = global::System.Linq.Expressions.Expression.Convert(expr_1, typeof(int));
            var expr_3 = global::System.Linq.Expressions.Expression.Constant("Weekday", typeof(string)); // "Weekday"
            var expr_6 = global::System.Linq.Expressions.Expression.Constant(0, typeof(int)); // 0
            var expr_5 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_6);
            var expr_8 = global::System.Linq.Expressions.Expression.Constant(6, typeof(int)); // 6
            var expr_7 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_8);
            var expr_4 = global::System.Linq.Expressions.Expression.OrElse(expr_5, expr_7);
            var expr_9 = global::System.Linq.Expressions.Expression.Constant("Weekend", typeof(string)); // "Weekend"
            var expr_10 = global::System.Linq.Expressions.Expression.Condition(expr_4, expr_9, expr_3, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order, string>>(expr_10, p_o);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_OrderExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_OrderExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.OrderExt).GetMethod("GetDayType", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_OrderExt", "GetDayType_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "OK5nD10Mw22YcqjjspYKfX8BAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_21<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: o => new { o.Id, Type = o.GetDayType() }
            var i3e6114c21_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "o");
            var i3e6114c21_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c21_p_o, typeof(T0).GetProperty("Id", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // o.Id
            var i3e6114c21_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.OrderExt).GetMethod("GetDayType", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c21_p_o }); // o.GetDayType()
            var i3e6114c21_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c21_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c21_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c21_expr_1, i3e6114c21_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Type") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c21_expr_0, i3e6114c21_p_o);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

when Guards

Guards add additional boolean conditions to switch arms:

db
    .LineItems
    .Select(i => new { i.Id, Tag = i.Classify() })

// Setup
public static class LineItemExt
{
    [Expressive]
    public static string Classify(this LineItem i) => i.Quantity switch
    {
        > 100 when i.UnitPrice < 10m => "Bulk Bargain",
        > 100                        => "Bulk Order",
        > 0                          => "Standard",
        _                            => "Empty",
    };
}
SELECT "l"."Id", CASE
    WHEN "l"."Quantity" > 100 AND ef_compare("l"."UnitPrice", '10.0') < 0 THEN 'Bulk Bargain'
    WHEN "l"."Quantity" > 100 THEN 'Bulk Order'
    WHEN "l"."Quantity" > 0 THEN 'Standard'
    ELSE 'Empty'
END AS "Tag"
FROM "LineItems" AS "l"
SELECT l."Id", CASE
    WHEN l."Quantity" > 100 AND l."UnitPrice" < 10.0 THEN 'Bulk Bargain'
    WHEN l."Quantity" > 100 THEN 'Bulk Order'
    WHEN l."Quantity" > 0 THEN 'Standard'
    ELSE 'Empty'
END AS "Tag"
FROM "LineItems" AS l
SELECT [l].[Id], CASE
    WHEN [l].[Quantity] > 100 AND [l].[UnitPrice] < 10.0 THEN N'Bulk Bargain'
    WHEN [l].[Quantity] > 100 THEN N'Bulk Order'
    WHEN [l].[Quantity] > 0 THEN N'Standard'
    ELSE N'Empty'
END AS [Tag]
FROM [LineItems] AS [l]
playground.line_items.Aggregate([
    {
         "$project" : {
             "_id" : "$_id",
            "Tag" : {
                 "$cond" : {
                     "if" : {
                         "$and" : [
                            {
                                 "$gt" : ["$Quantity", 100] 
                            },
                            {
                                 "$lt" : [
                                    "$UnitPrice",
                                    { "$numberDecimal" : "10" }
                                ] 
                            }
                        ] 
                    },
                    "then" : "Bulk Bargain",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$gt" : ["$Quantity", 100] 
                            },
                            "then" : "Bulk Order",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$gt" : ["$Quantity", 0] 
                                    },
                                    "then" : "Standard",
                                    "else" : "Empty" 
                                } 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_LineItemExt.Classify_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_LineItemExt 
    {
        // [Expressive]
        // public static string Classify(this LineItem i) => i.Quantity switch
        // {
        //     > 100 when i.UnitPrice < 10m => "Bulk Bargain",
        //     > 100 => "Bulk Order",
        //     > 0 => "Standard",
        //     _ => "Empty",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem, string>> Classify_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem_Expression() 
        {
            var p_i = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem), "i");
            var expr_0 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("Quantity", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // i.Quantity
            var expr_1 = global::System.Linq.Expressions.Expression.Constant("Empty", typeof(string)); // "Empty"
            var expr_3 = global::System.Linq.Expressions.Expression.Constant(0, typeof(int)); // 0
            var expr_2 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThan, expr_0, expr_3);
            var expr_4 = global::System.Linq.Expressions.Expression.Constant("Standard", typeof(string)); // "Standard"
            var expr_5 = global::System.Linq.Expressions.Expression.Condition(expr_2, expr_4, expr_1, typeof(string));
            var expr_7 = global::System.Linq.Expressions.Expression.Constant(100, typeof(int)); // 100
            var expr_6 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThan, expr_0, expr_7);
            var expr_8 = global::System.Linq.Expressions.Expression.Constant("Bulk Order", typeof(string)); // "Bulk Order"
            var expr_9 = global::System.Linq.Expressions.Expression.Condition(expr_6, expr_8, expr_5, typeof(string));
            var expr_11 = global::System.Linq.Expressions.Expression.Constant(100, typeof(int)); // 100
            var expr_10 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThan, expr_0, expr_11);
            var expr_13 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("UnitPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // i.UnitPrice
            var expr_14 = global::System.Linq.Expressions.Expression.Constant(10m, typeof(decimal)); // 10m
            var expr_12 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.LessThan, expr_13, expr_14);
            var expr_15 = global::System.Linq.Expressions.Expression.AndAlso(expr_10, expr_12);
            var expr_16 = global::System.Linq.Expressions.Expression.Constant("Bulk Bargain", typeof(string)); // "Bulk Bargain"
            var expr_17 = global::System.Linq.Expressions.Expression.Condition(expr_15, expr_16, expr_9, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem, string>>(expr_17, p_i);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_LineItemExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_LineItemExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.LineItemExt).GetMethod("Classify", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_LineItemExt", "Classify_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "rGTCBxuwyxBnN3do6Abr/IIBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_24<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: i => new { i.Id, Tag = i.Classify() }
            var i3e6114c24_p_i = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "i");
            var i3e6114c24_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c24_p_i, typeof(T0).GetProperty("Id", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // i.Id
            var i3e6114c24_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.LineItemExt).GetMethod("Classify", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c24_p_i }); // i.Classify()
            var i3e6114c24_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c24_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c24_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c24_expr_1, i3e6114c24_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Tag") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c24_expr_0, i3e6114c24_p_i);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

The guard condition is combined with the pattern using && in the generated expression, which each provider renders as part of its conditional form.

Type Patterns with Declaration Variables

Switch arms can match on type and bind the result to a variable:

csharp
[Expressive]
public static string Describe(this Animal animal) => animal switch
{
    Dog d   => $"Dog named {d.Name}",
    Cat c   => $"Cat: {c.Breed}",
    _       => "Unknown animal",
};

The generator produces type-check and cast expressions:

csharp
animal is Dog ? $"Dog named {((Dog)animal).Name}"
: animal is Cat ? $"Cat: {((Cat)animal).Breed}"
: "Unknown animal"

INFO

Declaration variables work within switch arms. The generated expression binds them via cast expressions. This is particularly useful for EF Core inheritance hierarchies (TPH, TPT, TPC).

Constant Patterns

Match against specific constant values:

db
    .Orders
    .Select(o => new { o.Id, Label = o.StatusLabel() })

// Setup
public static class OrderExt
{
    [Expressive]
    public static string StatusLabel(this Order o) => (int)o.Status switch
    {
        0 => "Pending",
        1 => "Paid",
        2 => "Shipped",
        3 => "Delivered",
        4 => "Refunded",
        _ => "Unknown",
    };
}
SELECT "o"."Id", CASE
    WHEN "o"."Status" = 0 THEN 'Pending'
    WHEN "o"."Status" = 1 THEN 'Paid'
    WHEN "o"."Status" = 2 THEN 'Shipped'
    WHEN "o"."Status" = 3 THEN 'Delivered'
    WHEN "o"."Status" = 4 THEN 'Refunded'
    ELSE 'Unknown'
END AS "Label"
FROM "Orders" AS "o"
SELECT o."Id", CASE
    WHEN o."Status" = 0 THEN 'Pending'
    WHEN o."Status" = 1 THEN 'Paid'
    WHEN o."Status" = 2 THEN 'Shipped'
    WHEN o."Status" = 3 THEN 'Delivered'
    WHEN o."Status" = 4 THEN 'Refunded'
    ELSE 'Unknown'
END AS "Label"
FROM "Orders" AS o
SELECT [o].[Id], CASE
    WHEN [o].[Status] = 0 THEN N'Pending'
    WHEN [o].[Status] = 1 THEN N'Paid'
    WHEN [o].[Status] = 2 THEN N'Shipped'
    WHEN [o].[Status] = 3 THEN N'Delivered'
    WHEN [o].[Status] = 4 THEN N'Refunded'
    ELSE N'Unknown'
END AS [Label]
FROM [Orders] AS [o]
playground.orders.Aggregate([
    {
         "$project" : {
             "_id" : "$_id",
            "Label" : {
                 "$cond" : {
                     "if" : {
                         "$eq" : ["$Status", 0] 
                    },
                    "then" : "Pending",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$eq" : ["$Status", 1] 
                            },
                            "then" : "Paid",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$eq" : ["$Status", 2] 
                                    },
                                    "then" : "Shipped",
                                    "else" : {
                                         "$cond" : {
                                             "if" : {
                                                 "$eq" : ["$Status", 3] 
                                            },
                                            "then" : "Delivered",
                                            "else" : {
                                                 "$cond" : {
                                                     "if" : {
                                                         "$eq" : ["$Status", 4] 
                                                    },
                                                    "then" : "Refunded",
                                                    "else" : "Unknown" 
                                                } 
                                            } 
                                        } 
                                    } 
                                } 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_OrderExt.StatusLabel_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_OrderExt 
    {
        // [Expressive]
        // public static string StatusLabel(this Order o) => (int)o.Status switch
        // {
        //     0 => "Pending",
        //     1 => "Paid",
        //     2 => "Shipped",
        //     3 => "Delivered",
        //     4 => "Refunded",
        //     _ => "Unknown",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order, string>> StatusLabel_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order_Expression() 
        {
            var p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order), "o");
            var expr_1 = global::System.Linq.Expressions.Expression.Property(p_o, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order).GetProperty("Status", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // o.Status
            var expr_0 = global::System.Linq.Expressions.Expression.Convert(expr_1, typeof(int));
            var expr_2 = global::System.Linq.Expressions.Expression.Constant("Unknown", typeof(string)); // "Unknown"
            var expr_4 = global::System.Linq.Expressions.Expression.Constant(4, typeof(int)); // 4
            var expr_3 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_4);
            var expr_5 = global::System.Linq.Expressions.Expression.Constant("Refunded", typeof(string)); // "Refunded"
            var expr_6 = global::System.Linq.Expressions.Expression.Condition(expr_3, expr_5, expr_2, typeof(string));
            var expr_8 = global::System.Linq.Expressions.Expression.Constant(3, typeof(int)); // 3
            var expr_7 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_8);
            var expr_9 = global::System.Linq.Expressions.Expression.Constant("Delivered", typeof(string)); // "Delivered"
            var expr_10 = global::System.Linq.Expressions.Expression.Condition(expr_7, expr_9, expr_6, typeof(string));
            var expr_12 = global::System.Linq.Expressions.Expression.Constant(2, typeof(int)); // 2
            var expr_11 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_12);
            var expr_13 = global::System.Linq.Expressions.Expression.Constant("Shipped", typeof(string)); // "Shipped"
            var expr_14 = global::System.Linq.Expressions.Expression.Condition(expr_11, expr_13, expr_10, typeof(string));
            var expr_16 = global::System.Linq.Expressions.Expression.Constant(1, typeof(int)); // 1
            var expr_15 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_16);
            var expr_17 = global::System.Linq.Expressions.Expression.Constant("Paid", typeof(string)); // "Paid"
            var expr_18 = global::System.Linq.Expressions.Expression.Condition(expr_15, expr_17, expr_14, typeof(string));
            var expr_20 = global::System.Linq.Expressions.Expression.Constant(0, typeof(int)); // 0
            var expr_19 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_20);
            var expr_21 = global::System.Linq.Expressions.Expression.Constant("Pending", typeof(string)); // "Pending"
            var expr_22 = global::System.Linq.Expressions.Expression.Condition(expr_19, expr_21, expr_18, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order, string>>(expr_22, p_o);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_OrderExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_OrderExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.OrderExt).GetMethod("StatusLabel", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Order) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_OrderExt", "StatusLabel_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Order_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "XadnDf3w0XwXKSdUA9+PHX8BAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_21<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: o => new { o.Id, Label = o.StatusLabel() }
            var i3e6114c21_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "o");
            var i3e6114c21_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c21_p_o, typeof(T0).GetProperty("Id", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // o.Id
            var i3e6114c21_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.OrderExt).GetMethod("StatusLabel", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c21_p_o }); // o.StatusLabel()
            var i3e6114c21_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c21_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c21_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c21_expr_1, i3e6114c21_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Label") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c21_expr_0, i3e6114c21_p_o);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

Nested Switch Expressions

Switch expressions can be nested for multi-dimensional classification:

db
    .Products
    .Select(p => new { p.Name, Priority = p.GetPriority() })

// Setup
public static class ProductExt
{
    [Expressive]
    public static string GetPriority(this Product p) => p.Category switch
    {
        "Electronics" => p.ListPrice switch
        {
            >= 500m => "High",
            >= 100m => "Medium",
            _       => "Low",
        },
        "Food" => "Standard",
        _      => "Default",
    };
}
SELECT "p"."Name", CASE
    WHEN "p"."Category" = 'Electronics' THEN CASE
        WHEN ef_compare("p"."ListPrice", '500.0') >= 0 THEN 'High'
        WHEN ef_compare("p"."ListPrice", '100.0') >= 0 THEN 'Medium'
        ELSE 'Low'
    END
    WHEN "p"."Category" = 'Food' THEN 'Standard'
    ELSE 'Default'
END AS "Priority"
FROM "Products" AS "p"
SELECT p."Name", CASE
    WHEN p."Category" = 'Electronics' THEN CASE
        WHEN p."ListPrice" >= 500.0 THEN 'High'
        WHEN p."ListPrice" >= 100.0 THEN 'Medium'
        ELSE 'Low'
    END
    WHEN p."Category" = 'Food' THEN 'Standard'
    ELSE 'Default'
END AS "Priority"
FROM "Products" AS p
SELECT [p].[Name], CASE
    WHEN [p].[Category] = N'Electronics' THEN CASE
        WHEN [p].[ListPrice] >= 500.0 THEN N'High'
        WHEN [p].[ListPrice] >= 100.0 THEN N'Medium'
        ELSE N'Low'
    END
    WHEN [p].[Category] = N'Food' THEN N'Standard'
    ELSE N'Default'
END AS [Priority]
FROM [Products] AS [p]
playground.products.Aggregate([
    {
         "$project" : {
             "Name" : "$Name",
            "Priority" : {
                 "$cond" : {
                     "if" : {
                         "$eq" : ["$Category", "Electronics"] 
                    },
                    "then" : {
                         "$cond" : {
                             "if" : {
                                 "$gte" : [
                                    "$ListPrice",
                                    { "$numberDecimal" : "500" }
                                ] 
                            },
                            "then" : "High",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$gte" : [
                                            "$ListPrice",
                                            { "$numberDecimal" : "100" }
                                        ] 
                                    },
                                    "then" : "Medium",
                                    "else" : "Low" 
                                } 
                            } 
                        } 
                    },
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$eq" : ["$Category", "Food"] 
                            },
                            "then" : "Standard",
                            "else" : "Default" 
                        } 
                    } 
                } 
            },
            "_id" : 0 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.GetPriority_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt 
    {
        // [Expressive]
        // public static string GetPriority(this Product p) => p.Category switch
        // {
        //     "Electronics" => p.ListPrice switch
        //     {
        //         >= 500m => "High",
        //         >= 100m => "Medium",
        //         _ => "Low",
        //     },
        //     "Food" => "Standard",
        //     _ => "Default",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>> GetPriority_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression() 
        {
            var p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product), "p");
            var expr_0 = global::System.Linq.Expressions.Expression.Property(p_p, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product).GetProperty("Category", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.Category
            var expr_1 = global::System.Linq.Expressions.Expression.Constant("Default", typeof(string)); // "Default"
            var expr_3 = global::System.Linq.Expressions.Expression.Constant("Food", typeof(string)); // "Food"
            var expr_2 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_3);
            var expr_4 = global::System.Linq.Expressions.Expression.Constant("Standard", typeof(string)); // "Standard"
            var expr_5 = global::System.Linq.Expressions.Expression.Condition(expr_2, expr_4, expr_1, typeof(string));
            var expr_7 = global::System.Linq.Expressions.Expression.Constant("Electronics", typeof(string)); // "Electronics"
            var expr_6 = global::System.Linq.Expressions.Expression.Equal(expr_0, expr_7);
            var expr_8 = global::System.Linq.Expressions.Expression.Property(p_p, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product).GetProperty("ListPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.ListPrice
            var expr_9 = global::System.Linq.Expressions.Expression.Constant("Low", typeof(string)); // "Low"
            var expr_11 = global::System.Linq.Expressions.Expression.Constant(100m, typeof(decimal)); // 100m
            var expr_10 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_8, expr_11);
            var expr_12 = global::System.Linq.Expressions.Expression.Constant("Medium", typeof(string)); // "Medium"
            var expr_13 = global::System.Linq.Expressions.Expression.Condition(expr_10, expr_12, expr_9, typeof(string));
            var expr_15 = global::System.Linq.Expressions.Expression.Constant(500m, typeof(decimal)); // 500m
            var expr_14 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_8, expr_15);
            var expr_16 = global::System.Linq.Expressions.Expression.Constant("High", typeof(string)); // "High"
            var expr_17 = global::System.Linq.Expressions.Expression.Condition(expr_14, expr_16, expr_13, typeof(string));
            var expr_18 = global::System.Linq.Expressions.Expression.Condition(expr_6, expr_17, expr_5, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product, string>>(expr_18, p_p);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_ProductExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_ProductExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetPriority", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.Product) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_ProductExt", "GetPriority_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_Product_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "g+kyLQ8m2xlz0solLkv2AYEBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_23<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: p => new { p.Name, Priority = p.GetPriority() }
            var i3e6114c23_p_p = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "p");
            var i3e6114c23_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c23_p_p, typeof(T0).GetProperty("Name", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // p.Name
            var i3e6114c23_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.ProductExt).GetMethod("GetPriority", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c23_p_p }); // p.GetPriority()
            var i3e6114c23_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c23_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c23_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c23_expr_1, i3e6114c23_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Name"), typeof(T1).GetProperty("Priority") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c23_expr_0, i3e6114c23_p_p);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

Property Patterns in Switch Arms

Match against an object's properties:

db
    .LineItems
    .Select(i => new { i.Id, Tag = i.ClassifyItem() })

// Setup
public static class LineItemExt
{
    [Expressive]
    public static string ClassifyItem(this LineItem i) => i switch
    {
        { Quantity: > 100, UnitPrice: >= 50m } => "Large Premium",
        { Quantity: > 100 }                    => "Large Standard",
        { UnitPrice: >= 50m }                  => "Small Premium",
        _                                      => "Small Standard",
    };
}
SELECT "l"."Id", CASE
    WHEN "l"."Quantity" > 100 AND ef_compare("l"."UnitPrice", '50.0') >= 0 THEN 'Large Premium'
    WHEN "l"."Quantity" > 100 THEN 'Large Standard'
    WHEN ef_compare("l"."UnitPrice", '50.0') >= 0 THEN 'Small Premium'
    ELSE 'Small Standard'
END AS "Tag"
FROM "LineItems" AS "l"
SELECT l."Id", CASE
    WHEN l."Quantity" > 100 AND l."UnitPrice" >= 50.0 THEN 'Large Premium'
    WHEN l."Quantity" > 100 THEN 'Large Standard'
    WHEN l."UnitPrice" >= 50.0 THEN 'Small Premium'
    ELSE 'Small Standard'
END AS "Tag"
FROM "LineItems" AS l
SELECT [l].[Id], CASE
    WHEN [l].[Quantity] > 100 AND [l].[UnitPrice] >= 50.0 THEN N'Large Premium'
    WHEN [l].[Quantity] > 100 THEN N'Large Standard'
    WHEN [l].[UnitPrice] >= 50.0 THEN N'Small Premium'
    ELSE N'Small Standard'
END AS [Tag]
FROM [LineItems] AS [l]
playground.line_items.Aggregate([
    {
         "$project" : {
             "_id" : "$_id",
            "Tag" : {
                 "$cond" : {
                     "if" : {
                         "$and" : [
                            {
                                 "$ne" : ["$$ROOT", null] 
                            },
                            {
                                 "$gt" : ["$Quantity", 100] 
                            },
                            {
                                 "$gte" : [
                                    "$UnitPrice",
                                    { "$numberDecimal" : "50" }
                                ] 
                            }
                        ] 
                    },
                    "then" : "Large Premium",
                    "else" : {
                         "$cond" : {
                             "if" : {
                                 "$and" : [
                                    {
                                         "$ne" : ["$$ROOT", null] 
                                    },
                                    {
                                         "$gt" : ["$Quantity", 100] 
                                    }
                                ] 
                            },
                            "then" : "Large Standard",
                            "else" : {
                                 "$cond" : {
                                     "if" : {
                                         "$and" : [
                                            {
                                                 "$ne" : ["$$ROOT", null] 
                                            },
                                            {
                                                 "$gte" : [
                                                    "$UnitPrice",
                                                    { "$numberDecimal" : "50" }
                                                ] 
                                            }
                                        ] 
                                    },
                                    "then" : "Small Premium",
                                    "else" : "Small Standard" 
                                } 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    }
])
// === ExpressiveSharp_Docs_Playground_Snippet_LineItemExt.ClassifyItem_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Linq;
using System.Linq.Expressions;
using ExpressiveSharp;
using ExpressiveSharp.EntityFrameworkCore;
using ExpressiveSharp.Docs.PlaygroundModel.Webshop;
using ExpressiveSharp.Docs.Playground.Snippet;

namespace ExpressiveSharp.Generated
{
    static partial class ExpressiveSharp_Docs_Playground_Snippet_LineItemExt 
    {
        // [Expressive]
        // public static string ClassifyItem(this LineItem i) => i switch
        // {
        //     { Quantity: > 100, UnitPrice: >= 50m } => "Large Premium",
        //     { Quantity: > 100 } => "Large Standard",
        //     { UnitPrice: >= 50m } => "Small Premium",
        //     _ => "Small Standard",
        // };
        static global::System.Linq.Expressions.Expression<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem, string>> ClassifyItem_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem_Expression() 
        {
            var p_i = global::System.Linq.Expressions.Expression.Parameter(typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem), "i");
            var expr_0 = global::System.Linq.Expressions.Expression.Constant("Small Standard", typeof(string)); // "Small Standard"
            var expr_2 = global::System.Linq.Expressions.Expression.Constant(null, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem));
            var expr_1 = global::System.Linq.Expressions.Expression.NotEqual(p_i, expr_2);
            var expr_3 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("UnitPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance));
            var expr_5 = global::System.Linq.Expressions.Expression.Constant(50m, typeof(decimal)); // 50m
            var expr_4 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_3, expr_5);
            var expr_6 = global::System.Linq.Expressions.Expression.AndAlso(expr_1, expr_4);
            var expr_7 = global::System.Linq.Expressions.Expression.Constant("Small Premium", typeof(string)); // "Small Premium"
            var expr_8 = global::System.Linq.Expressions.Expression.Condition(expr_6, expr_7, expr_0, typeof(string));
            var expr_10 = global::System.Linq.Expressions.Expression.Constant(null, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem));
            var expr_9 = global::System.Linq.Expressions.Expression.NotEqual(p_i, expr_10);
            var expr_11 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("Quantity", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance));
            var expr_13 = global::System.Linq.Expressions.Expression.Constant(100, typeof(int)); // 100
            var expr_12 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThan, expr_11, expr_13);
            var expr_14 = global::System.Linq.Expressions.Expression.AndAlso(expr_9, expr_12);
            var expr_15 = global::System.Linq.Expressions.Expression.Constant("Large Standard", typeof(string)); // "Large Standard"
            var expr_16 = global::System.Linq.Expressions.Expression.Condition(expr_14, expr_15, expr_8, typeof(string));
            var expr_18 = global::System.Linq.Expressions.Expression.Constant(null, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem));
            var expr_17 = global::System.Linq.Expressions.Expression.NotEqual(p_i, expr_18);
            var expr_19 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("Quantity", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance));
            var expr_21 = global::System.Linq.Expressions.Expression.Constant(100, typeof(int)); // 100
            var expr_20 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThan, expr_19, expr_21);
            var expr_22 = global::System.Linq.Expressions.Expression.Property(p_i, typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem).GetProperty("UnitPrice", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance));
            var expr_24 = global::System.Linq.Expressions.Expression.Constant(50m, typeof(decimal)); // 50m
            var expr_23 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.GreaterThanOrEqual, expr_22, expr_24);
            var expr_25 = global::System.Linq.Expressions.Expression.AndAlso(expr_17, expr_20);
            var expr_26 = global::System.Linq.Expressions.Expression.AndAlso(expr_25, expr_23);
            var expr_27 = global::System.Linq.Expressions.Expression.Constant("Large Premium", typeof(string)); // "Large Premium"
            var expr_28 = global::System.Linq.Expressions.Expression.Condition(expr_26, expr_27, expr_16, typeof(string));
            return global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem, string>>(expr_28, p_i);
        }
    }
}


// === ExpressiveSharp_Docs_Playground_Snippet_LineItemExt.Attributes.g.cs ===
// <auto-generated/>

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    static partial class ExpressiveSharp_Docs_Playground_Snippet_LineItemExt { }
}


// === ExpressionRegistry.g.cs ===
// <auto-generated/>
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressiveSharp.Generated
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    internal static class ExpressionRegistry
    {
        private static Dictionary<nint, LambdaExpression> Build()
        {
            const BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var map = new Dictionary<nint, LambdaExpression>();
            
            Register(map, typeof(global::ExpressiveSharp.Docs.Playground.Snippet.LineItemExt).GetMethod("ClassifyItem", allFlags, null, new global::System.Type[] { typeof(global::ExpressiveSharp.Docs.PlaygroundModel.Webshop.LineItem) }, null), "ExpressiveSharp.Generated.ExpressiveSharp_Docs_Playground_Snippet_LineItemExt", "ClassifyItem_P0_ExpressiveSharp_Docs_PlaygroundModel_Webshop_LineItem_Expression");
            
            return map;
        }
        
        private static volatile Dictionary<nint, LambdaExpression> _map = Build();
        
        internal static void ResetMap() => _map = Build();
        
        public static LambdaExpression TryGet(MemberInfo member)
        {
            var handle = member switch
            {
                MethodInfo m      => (nint?)m.MethodHandle.Value,
                PropertyInfo p    => p.GetMethod?.MethodHandle.Value,
                ConstructorInfo c => (nint?)c.MethodHandle.Value,
                _                 => null
            };
            
            return handle.HasValue && _map.TryGetValue(handle.Value, out var expr) ? expr : null;
        }
        
        private static void Register(Dictionary<nint, LambdaExpression> map, MethodBase m, string exprClass, string exprMethodName)
        {
            if (m is null) return;
            var exprType = m.DeclaringType?.Assembly.GetType(exprClass) ?? typeof(ExpressionRegistry).Assembly.GetType(exprClass);
            var exprMethod = exprType?.GetMethod(exprMethodName, BindingFlags.Static | BindingFlags.NonPublic);
            if (exprMethod is null) return;
            var expr = (LambdaExpression)exprMethod.Invoke(null, null)!;
            
            // Apply declared transformers from the generated class (if any)
            const string expressionSuffix = "_Expression";
            if (exprMethodName.EndsWith(expressionSuffix, StringComparison.Ordinal))
            {
                var transformersSuffix = exprMethodName.Substring(0, exprMethodName.Length - expressionSuffix.Length) + "_Transformers";
                var transformersMethod = exprType.GetMethod(transformersSuffix, BindingFlags.Static | BindingFlags.NonPublic);
                if (transformersMethod?.Invoke(null, null) is global::ExpressiveSharp.IExpressionTreeTransformer[] transformers)
                {
                    Expression transformed = expr;
                    foreach (var t in transformers) transformed = t.Transform(transformed);
                    if (transformed is LambdaExpression lambdaResult) expr = lambdaResult;
                }
            }
            
            map[m.MethodHandle.Value] = expr;
        }
    }
}


// === PolyfillInterceptors_b1293e61.g.cs ===
// <auto-generated/>
#nullable disable

namespace ExpressiveSharp.Generated.Interceptors
{
    internal static partial class PolyfillInterceptors
    {
        [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "geA7+xo3OGLKCksgqbWzpYIBAABfX1NuaXBwZXQuY3M=")]
        internal static global::ExpressiveSharp.IExpressiveQueryable<T1> __Polyfill_Select_3e61_14_24<T0, T1>(
            this global::ExpressiveSharp.IExpressiveQueryable<T0> source,
            global::System.Func<T0, T1> __func)
        {
            // Source: i => new { i.Id, Tag = i.ClassifyItem() }
            var i3e6114c24_p_i = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "i");
            var i3e6114c24_expr_1 = global::System.Linq.Expressions.Expression.Property(i3e6114c24_p_i, typeof(T0).GetProperty("Id", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance)); // i.Id
            var i3e6114c24_expr_2 = global::System.Linq.Expressions.Expression.Call(typeof(global::ExpressiveSharp.Docs.Playground.Snippet.LineItemExt).GetMethod("ClassifyItem", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static, null, new global::System.Type[] { typeof(T0) }, null), new global::System.Linq.Expressions.Expression[] { i3e6114c24_p_i }); // i.ClassifyItem()
            var i3e6114c24_expr_3 = typeof(T1).GetConstructors()[0];
            var i3e6114c24_expr_0 = global::System.Linq.Expressions.Expression.New(i3e6114c24_expr_3, new global::System.Linq.Expressions.Expression[] { i3e6114c24_expr_1, i3e6114c24_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Tag") });
            var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i3e6114c24_expr_0, i3e6114c24_p_i);
            return (global::ExpressiveSharp.IExpressiveQueryable<T1>)(object)
                global::ExpressiveSharp.ExpressiveQueryableExtensions.AsExpressive(
                    global::System.Linq.Queryable.Select(
                        (global::System.Linq.IQueryable<T0>)(object)source,
                        __lambda));
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : global::System.Attribute
    {
        public InterceptsLocationAttribute(int version, string data) { }
    }
}

Pattern-to-Condition Cheat Sheet

All switch expressions map to conditional expressions in the target language (SQL CASE, MongoDB $switch, etc.). Here is a summary of how different patterns translate at the C# layer:

C# PatternGenerated Condition
>= 100col >= 100
>= 80 and < 90col >= 80 && col < 90
1 or 2col == 1 || col == 2
"Premium"col == "Premium"
_ (discard)fallback (else) branch
> 50 when Flagcol > 50 && Flag

Best Practices

  1. Always include a discard arm (_) to ensure the conditional has a fallback branch.

  2. Keep arms simple for translation. Each arm's pattern and result should be a simple expression. Avoid calling methods that cannot be translated by your provider.

  3. Order arms from most specific to least specific, just as you would in C#. The generated ternary chain evaluates top-to-bottom, matching the provider's conditional evaluation order.

  4. Prefer switch expressions over nested ternaries for readability. The source generator produces ternary chains regardless, but the switch expression in your source code is easier to read and maintain.

  5. Use [Expressive] methods for complex switches rather than inline switch expressions in queries:

    csharp
    // Prefer this: reusable and readable
    [Expressive]
    public string GetGrade() => Price switch { ... };
    
    // Over this: inline in every query
    db.Orders.Select(o => o.Price switch { ... });

See also Pattern Matching for the full list of supported patterns.

Released under the MIT License.