You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Global Usings — avoid repetitive `using` directives
95
+
### Global Usings - avoid repetitive `using` directives
96
96
97
97
Because domain types are spread across multiple namespaces, we strongly recommend adding a single `GlobalUsings.cs` file at the root of your project. This is a standard C# feature that applies `using` directives project-wide, so you never have to repeat them in individual files.
98
98
@@ -116,7 +116,7 @@ global using StrongOf.Domains.Software;
116
116
After this one-time setup, all domain types are available everywhere in your project without any further imports:
117
117
118
118
```csharp
119
-
// No using directives needed — GlobalUsings.cs already covers them
119
+
// No using directives needed - GlobalUsings.cs already covers them
120
120
publicclassUser
121
121
{
122
122
publicTenantIdTenantId { get; set; }
@@ -128,7 +128,7 @@ public class User
128
128
}
129
129
```
130
130
131
-
> **Tip:** Global usings are evaluated at compile-time and have zero runtime overhead. They were introduced in C# 10 / .NET 6 and are a first-class language feature — not a workaround.
131
+
> **Tip:** Global usings are evaluated at compile-time and have zero runtime overhead. They were introduced in C# 10 / .NET 6 and are a first-class language feature - not a workaround.
132
132
133
133
### Namespace naming rationale
134
134
@@ -208,19 +208,72 @@ public class MyCustomStrongGuidBinder<TStrong> : StrongOfBinder
208
208
}
209
209
```
210
210
211
-
## Usage with Entity Framework
211
+
## Usage with Entity Framework Core
212
212
213
-
Unfortunately, Entity Framework does not love generic [Value Converters](https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions?WT.mc_id=DT-MVP-5001507), which is why you have to write it yourself.
213
+
Install [StrongOf.EntityFrameworkCore](https://www.nuget.org/packages/StrongOf.EntityFrameworkCore) for first-class EF Core integration with a generic value converter that works for all strong types - no per-type converter classes needed.
214
+
215
+
```bash
216
+
dotnet add package StrongOf.EntityFrameworkCore
217
+
```
218
+
219
+
### Register Converters Once with `ConfigureConventions` (Recommended)
220
+
221
+
Register each strong type once in `ConfigureConventions` and EF Core applies the converter globally across all entities and `DbSet`s - no per-property configuration required:
EF Core value converters work transparently for CRUD, equality comparisons (`==`, `!=`), and ordering. However, be aware of these limitations:
266
+
267
+
-**`.Value` in LINQ** - not translatable to SQL. Compare strong types against strong types instead.
268
+
-**`Contains` with mixed types** - the list must be the strong type (`UserId`), not the primitive (`Guid`). Use `UserId.From(guids)` to convert.
269
+
-**`ToString()` in LINQ** - not translatable. Format client-side after materializing.
270
+
-**Aggregations** - may require casting to the nullable primitive type (e.g. `(decimal?)order.Total`).
271
+
272
+
See the [StrongOf.EntityFrameworkCore readme](src/StrongOf.EntityFrameworkCore/readme.md) for detailed examples and a full compatibility table.
273
+
274
+
### Why No Source Generator for EF Core?
275
+
276
+
The generic `StrongOfValueConverter<TStrong, TTarget>` already eliminates all per-type boilerplate. Combined with `ConfigureConventions`, registration is a single line per type. A source generator would add Roslyn coupling complexity and contradicts the project's design philosophy (see FAQ below) - for zero practical benefit.
0 commit comments