-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
65 lines (63 loc) · 33.7 KB
/
index.html
File metadata and controls
65 lines (63 loc) · 33.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>EF Core Projectables</title>
<meta name="description" content="Flexible projection magic for EF Core — use properties and methods directly in your LINQ queries">
<meta name="generator" content="VitePress v2.0.0-alpha.17">
<link rel="preload stylesheet" href="/assets/style.CpczRDX8.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.Bxp6RXxZ.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Cy4MYw_J.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.UqmxTBg7.js">
<link rel="modulepreload" href="/assets/chunks/framework.YJN_DkY-.js">
<link rel="modulepreload" href="/assets/index.md.CtMSAYK8.lean.js">
<link rel="icon" type="image/svg+xml" href="/logo.svg">
<meta property="og:image" content="https://efnext.github.io/social.svg">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://efnext.github.io/social.svg">
<script defer src="https://cloud.umami.is/script.js" data-website-id="ccd38f75-b037-4535-abe6-3794413f607c"></script>
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-c109192d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-10d4d845></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-10d4d845>Skip to content</a><!--]--><!----><header class="VPNav" data-v-c109192d data-v-d5bf7c8e><div class="VPNavBar home top" data-v-d5bf7c8e data-v-cc1d9f2e><div class="wrapper" data-v-cc1d9f2e><div class="container" data-v-cc1d9f2e><div class="title" data-v-cc1d9f2e><div class="VPNavBarTitle" data-v-cc1d9f2e data-v-d4488dd0><a class="title" href="/" data-v-d4488dd0><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.svg" alt data-v-ab19afbb><!--]--><span data-v-d4488dd0>EF Core Projectables</span><!--[--><!--]--></a></div></div><div class="content" data-v-cc1d9f2e><div class="content-body" data-v-cc1d9f2e><!--[--><!--]--><div class="VPNavBarSearch search" data-v-cc1d9f2e data-v-bdd98725><!--[--><button type="button" class="VPNavBarSearchButton" aria-label="Search" aria-keyshortcuts="/ control+k meta+k" data-v-bdd98725 data-v-69351052><span class="vpi-search" aria-hidden="true" data-v-69351052></span><span class="text" data-v-69351052>Search</span><span class="keys" aria-hidden="true" data-v-69351052><kbd class="key-cmd" data-v-69351052>⌘</kbd><kbd class="key-ctrl" data-v-69351052>Ctrl</kbd><kbd data-v-69351052>K</kbd></span></button><!----><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-cc1d9f2e data-v-020be4db><span id="main-nav-aria-label" class="visually-hidden" data-v-020be4db> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink active" href="/" tabindex="0" data-v-020be4db data-v-727dd4ba><!--[--><span data-v-727dd4ba>Home</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/guide/introduction.html" tabindex="0" data-v-020be4db data-v-727dd4ba><!--[--><span data-v-727dd4ba>Guide</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/reference/projectable-attribute.html" tabindex="0" data-v-020be4db data-v-727dd4ba><!--[--><span data-v-727dd4ba>Reference</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/advanced/how-it-works.html" tabindex="0" data-v-020be4db data-v-727dd4ba><!--[--><span data-v-727dd4ba>Advanced</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/recipes/computed-properties.html" tabindex="0" data-v-020be4db data-v-727dd4ba><!--[--><span data-v-727dd4ba>Recipes</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-cc1d9f2e data-v-3f90c1a5><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-3f90c1a5 data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-cc1d9f2e data-v-ef6192dc data-v-a1a7286e><!--[--><a class="VPSocialLink no-icon" href="https://github.com/EFNext/EntityFrameworkCore.Projectables" aria-label="github" target="_blank" rel="me noopener" data-v-a1a7286e data-v-32d78712><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-cc1d9f2e data-v-2a0cad91 data-v-d8fae6e2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-d8fae6e2><span class="vpi-more-horizontal icon" data-v-d8fae6e2></span></button><div class="menu" data-v-d8fae6e2><div class="VPMenu" data-v-d8fae6e2 data-v-fcd1d7a8><!----><!--[--><!--[--><!----><div class="group" data-v-2a0cad91><div class="item appearance" data-v-2a0cad91><p class="label" data-v-2a0cad91>Appearance</p><div class="appearance-action" data-v-2a0cad91><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-2a0cad91 data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div></div></div><div class="group" data-v-2a0cad91><div class="item social-links" data-v-2a0cad91><div class="VPSocialLinks social-links-list" data-v-2a0cad91 data-v-a1a7286e><!--[--><a class="VPSocialLink no-icon" href="https://github.com/EFNext/EntityFrameworkCore.Projectables" aria-label="github" target="_blank" rel="me noopener" data-v-a1a7286e data-v-32d78712><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-cc1d9f2e data-v-6bee1efd><span class="container" data-v-6bee1efd><span class="top" data-v-6bee1efd></span><span class="middle" data-v-6bee1efd></span><span class="bottom" data-v-6bee1efd></span></span></button></div></div></div></div><div class="divider" data-v-cc1d9f2e><div class="divider-line" data-v-cc1d9f2e></div></div></div><!----></header><!----><!----><div class="VPContent is-home" id="VPContent" data-v-c109192d data-v-529a4999><div class="VPHome" data-v-529a4999 data-v-3f294140><!--[--><!--]--><div class="VPHero VPHomeHero" data-v-3f294140 data-v-dba860da><div class="container" data-v-dba860da><div class="main" data-v-dba860da><!--[--><!--]--><!--[--><h1 class="heading" data-v-dba860da><span class="name clip" data-v-dba860da>EF Core Projectables</span><span class="text" data-v-dba860da>Flexible projection magic for EF Core</span></h1><p class="tagline" data-v-dba860da>Write properties and methods once — use them anywhere in your LINQ queries, translated to efficient SQL automatically.</p><!--]--><!--[--><!--]--><div class="actions" data-v-dba860da><!--[--><!--]--><!--[--><div class="action" data-v-dba860da><a class="VPButton medium brand" href="/guide/introduction.html" data-v-dba860da data-v-58d3b43b><!--[-->Introduction<!--]--></a></div><div class="action" data-v-dba860da><a class="VPButton medium alt" href="/guide/quickstart.html" data-v-dba860da data-v-58d3b43b><!--[-->Quick Start<!--]--></a></div><div class="action" data-v-dba860da><a class="VPButton medium alt" href="https://github.com/EFNext/EntityFrameworkCore.Projectables" target="_blank" rel="noreferrer" data-v-dba860da data-v-58d3b43b><!--[-->View on GitHub<!--]--></a></div><!--]--></div><!--[--><!--]--></div><!----></div></div><!--[--><!--]--><!--[--><!--]--><div class="VPFeatures VPHomeFeatures" data-v-3f294140 data-v-b1eea84a><div class="container" data-v-b1eea84a><div class="items" data-v-b1eea84a><!--[--><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🏷️</div><h2 class="title" data-v-83e454c5>Just Add [Projectable]</h2><p class="details" data-v-83e454c5>Decorate any property, method, or constructor with [Projectable] and the source generator does the rest — no boilerplate, no manual expression trees.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🔌</div><h2 class="title" data-v-83e454c5>Works with Any EF Core Provider</h2><p class="details" data-v-83e454c5>Provider-agnostic. SQL Server, PostgreSQL, SQLite, Cosmos DB — Projectables hooks into the EF Core query pipeline regardless of your database.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>⚡</div><h2 class="title" data-v-83e454c5>Performance-First Design</h2><p class="details" data-v-83e454c5>Limited compatibility mode expands and caches queries after their first execution. Subsequent calls skip the expansion step entirely.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🔗</div><h2 class="title" data-v-83e454c5>Composable by Design</h2><p class="details" data-v-83e454c5>Projectable members can call other projectable members. Build a library of reusable query fragments and compose them freely in any query.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🏗️</div><h2 class="title" data-v-83e454c5>Constructor Projections</h2><p class="details" data-v-83e454c5>Mark a constructor with [Projectable] to project your DTOs directly in queries — new CustomerDto(c) translates to a full SQL projection with member-init syntax.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🔀</div><h2 class="title" data-v-83e454c5>Pattern Matching Support</h2><p class="details" data-v-83e454c5>Use switch expressions, is patterns, relational patterns, and and/or combinators directly in projectable members — all rewritten into SQL CASE expressions automatically.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🛡️</div><h2 class="title" data-v-83e454c5>Null-Conditional Rewriting</h2><p class="details" data-v-83e454c5>Working with nullable navigation properties? Configure NullConditionalRewriteSupport to automatically handle the ?. operator in generated expressions.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🔢</div><h2 class="title" data-v-83e454c5>Enum Method Expansion</h2><p class="details" data-v-83e454c5>Use ExpandEnumMethods to translate enum extension methods (like display names from [Display] attributes) into SQL CASE expressions automatically.</p><!----></article><!--]--></div></div><div class="grid-6 item" data-v-b1eea84a><div class="VPLink no-icon VPFeature" data-v-b1eea84a data-v-83e454c5><!--[--><article class="box" data-v-83e454c5><div class="icon" data-v-83e454c5>🩺</div><h2 class="title" data-v-83e454c5>Roslyn Analyzers & Code Fixes</h2><p class="details" data-v-83e454c5>Built-in Roslyn diagnostics (EFP0001–EFP0012) catch projection errors at compile time. Quick-fix actions let you resolve them with a single click in your IDE.</p><!----></article><!--]--></div></div><!--]--></div></div></div><!--[--><!--]--><div class="vp-doc container" style="" data-v-3f294140 data-v-c141a4bd><!--[--><div style="position:relative;" data-v-3f294140><div><h2 id="at-a-glance" tabindex="-1">At a Glance <a class="header-anchor" href="#at-a-glance" aria-label="Permalink to “At a Glance”"></a></h2><p><strong>Without Projectables</strong> — the same sub-expression copy-pasted into every query:</p><div class="language-csharp"><button title="Copy Code" class="copy"></button><span class="lang">csharp</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// ❌ Repeated 4× in a single query — change the formula and hunt down every copy</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">var</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> orders</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dbContext.Orders</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Where</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Lines.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Sum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.Quantity </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.UnitPrice) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">OrderByDescending</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Lines.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Sum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.Quantity </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.UnitPrice) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.TaxRate))</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Select</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Total </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Lines.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Sum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.Quantity </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.UnitPrice) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.TaxRate),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Tier </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Lines.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Sum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.Quantity </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.UnitPrice) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1000</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Premium"</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Standard"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">ToList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span></code></pre></div><p><strong>With Projectables</strong> — define once on the entity, compose freely, use anywhere:</p><div class="language-csharp"><button title="Copy Code" class="copy"></button><span class="lang">csharp</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// ✅ Business logic lives on the entity — queries stay clean</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Order</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> decimal</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> TaxRate</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">set</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ICollection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">OrderLine</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">> </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Lines</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">set</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Projectable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> decimal</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Subtotal</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Lines.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Sum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.Quantity </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> l.UnitPrice);</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Projectable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> decimal</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Total</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Subtotal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> TaxRate); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// composes ↑</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Projectable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> string</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Tier</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Subtotal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">switch</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // pattern matching → SQL CASE</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1000</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Premium"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 250</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Standard"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Basic"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">var</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> orders</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dbContext.Orders</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Where</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Subtotal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// → WHERE</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">OrderByDescending</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> o.Total) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// → ORDER BY</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Select</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">o</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { o.Total, o.Tier }) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// → SELECT</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">ToList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span></code></pre></div><p>The properties are <strong>inlined into SQL at query time</strong> — no client-side evaluation, no N+1, no duplicate expressions.</p><h2 id="nuget-packages" tabindex="-1">NuGet Packages <a class="header-anchor" href="#nuget-packages" aria-label="Permalink to “NuGet Packages”"></a></h2><table tabindex="0"><thead><tr><th>Package</th><th>Description</th></tr></thead><tbody><tr><td><a href="https://www.nuget.org/packages/EntityFrameworkCore.Projectables.Abstractions/" target="_blank" rel="noreferrer"><code>EntityFrameworkCore.Projectables.Abstractions</code></a></td><td>The <code>[Projectable]</code> attribute and source generator</td></tr><tr><td><a href="https://www.nuget.org/packages/EntityFrameworkCore.Projectables/" target="_blank" rel="noreferrer"><code>EntityFrameworkCore.Projectables</code></a></td><td>The EF Core runtime extension</td></tr></tbody></table></div></div><!--]--></div></div></div><footer class="VPFooter" data-v-c109192d data-v-5b9946f5><div class="container" data-v-5b9946f5><p class="message" data-v-5b9946f5>Released under the MIT License.</p><p class="copyright" data-v-5b9946f5>Copyright © EntityFrameworkCore.Projectables Contributors</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"advanced_block-bodied-members.md\":\"CguypTLQ\",\"advanced_how-it-works.md\":\"C2lTo8Xn\",\"advanced_limitations.md\":\"D1ESgxtT\",\"advanced_query-compiler-pipeline.md\":\"DkOkxDIE\",\"guide_extension-methods.md\":\"BI2_wZqV\",\"guide_introduction.md\":\"CtqqA8K-\",\"guide_projectable-constructors.md\":\"CYjM1Drd\",\"guide_projectable-methods.md\":\"LEt4MGU9\",\"guide_projectable-properties.md\":\"hlIoEgG6\",\"guide_quickstart.md\":\"BToOmqA6\",\"index.md\":\"CtMSAYK8\",\"recipes_collection-aggregates.md\":\"DgrSgDkw\",\"recipes_computed-properties.md\":\"GdD10O7j\",\"recipes_dto-projections.md\":\"Cl7gidok\",\"recipes_enum-display-names.md\":\"DRF2qlWq\",\"recipes_nullable-navigation.md\":\"BUM6CUzq\",\"recipes_reusable-query-filters.md\":\"DFWFNsau\",\"recipes_scoring-classification.md\":\"BhLJdxfD\",\"reference_compatibility-mode.md\":\"id3xET9R\",\"reference_diagnostics.md\":\"DdPTIVDg\",\"reference_expand-enum-methods.md\":\"BweW5qU_\",\"reference_null-conditional-rewrite.md\":\"BP98MK00\",\"reference_pattern-matching.md\":\"CHXWA4tZ\",\"reference_projectable-attribute.md\":\"Mg1rU6Kp\",\"reference_use-member-body.md\":\"BNzZx2Mz\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"EF Core Projectables\",\"description\":\"Flexible projection magic for EF Core — use properties and methods directly in your LINQ queries\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.svg\",\"nav\":[{\"text\":\"Home\",\"link\":\"/\"},{\"text\":\"Guide\",\"link\":\"/guide/introduction\"},{\"text\":\"Reference\",\"link\":\"/reference/projectable-attribute\"},{\"text\":\"Advanced\",\"link\":\"/advanced/how-it-works\"},{\"text\":\"Recipes\",\"link\":\"/recipes/computed-properties\"}],\"sidebar\":{\"/guide/\":[{\"text\":\"Getting Started\",\"items\":[{\"text\":\"Introduction\",\"link\":\"/guide/introduction\"},{\"text\":\"Quick Start\",\"link\":\"/guide/quickstart\"}]},{\"text\":\"Core Concepts\",\"items\":[{\"text\":\"Projectable Properties\",\"link\":\"/guide/projectable-properties\"},{\"text\":\"Projectable Methods\",\"link\":\"/guide/projectable-methods\"},{\"text\":\"Extension Methods\",\"link\":\"/guide/extension-methods\"},{\"text\":\"Constructor Projections\",\"link\":\"/guide/projectable-constructors\"}]}],\"/reference/\":[{\"text\":\"Reference\",\"items\":[{\"text\":\"[Projectable] Attribute\",\"link\":\"/reference/projectable-attribute\"},{\"text\":\"Compatibility Mode\",\"link\":\"/reference/compatibility-mode\"},{\"text\":\"Null-Conditional Rewrite\",\"link\":\"/reference/null-conditional-rewrite\"},{\"text\":\"Pattern Matching\",\"link\":\"/reference/pattern-matching\"},{\"text\":\"Expand Enum Methods\",\"link\":\"/reference/expand-enum-methods\"},{\"text\":\"Use Member Body\",\"link\":\"/reference/use-member-body\"},{\"text\":\"Diagnostics & Code Fixes\",\"link\":\"/reference/diagnostics\"}]}],\"/advanced/\":[{\"text\":\"Advanced\",\"items\":[{\"text\":\"How It Works\",\"link\":\"/advanced/how-it-works\"},{\"text\":\"Query Compiler Pipeline\",\"link\":\"/advanced/query-compiler-pipeline\"},{\"text\":\"Block-Bodied Members\",\"link\":\"/advanced/block-bodied-members\"},{\"text\":\"Limitations\",\"link\":\"/advanced/limitations\"}]}],\"/recipes/\":[{\"text\":\"Recipes\",\"items\":[{\"text\":\"Computed Entity Properties\",\"link\":\"/recipes/computed-properties\"},{\"text\":\"DTO Projections with Constructors\",\"link\":\"/recipes/dto-projections\"},{\"text\":\"Scoring & Classification\",\"link\":\"/recipes/scoring-classification\"},{\"text\":\"Collection Aggregates\",\"link\":\"/recipes/collection-aggregates\"},{\"text\":\"Enum Display Names\",\"link\":\"/recipes/enum-display-names\"},{\"text\":\"Nullable Navigation Properties\",\"link\":\"/recipes/nullable-navigation\"},{\"text\":\"Reusable Query Filters\",\"link\":\"/recipes/reusable-query-filters\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/EFNext/EntityFrameworkCore.Projectables\"}],\"search\":{\"provider\":\"local\"},\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © EntityFrameworkCore.Projectables Contributors\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false,\"additionalConfig\":{}}");</script>
</body>
</html>