Tyto.Materializer.EntityFrameworkCore
0.0.1-alpha.47
dotnet add package Tyto.Materializer.EntityFrameworkCore --version 0.0.1-alpha.47
NuGet\Install-Package Tyto.Materializer.EntityFrameworkCore -Version 0.0.1-alpha.47
<PackageReference Include="Tyto.Materializer.EntityFrameworkCore" Version="0.0.1-alpha.47" />
<PackageVersion Include="Tyto.Materializer.EntityFrameworkCore" Version="0.0.1-alpha.47" />
<PackageReference Include="Tyto.Materializer.EntityFrameworkCore" />
paket add Tyto.Materializer.EntityFrameworkCore --version 0.0.1-alpha.47
#r "nuget: Tyto.Materializer.EntityFrameworkCore, 0.0.1-alpha.47"
#:package Tyto.Materializer.EntityFrameworkCore@0.0.1-alpha.47
#addin nuget:?package=Tyto.Materializer.EntityFrameworkCore&version=0.0.1-alpha.47&prerelease
#tool nuget:?package=Tyto.Materializer.EntityFrameworkCore&version=0.0.1-alpha.47&prerelease
Tyto.Materializer.EntityFrameworkCore
This package provides a robust IViewStore<TView, TKey> implementation using Entity Framework Core. It allows you to persist your read models as structured tables in a relational database (SQL Server, PostgreSQL, SQLite, etc.) while seamlessly integrating with EF Core's change tracking and native optimistic concurrency mechanisms.
🚀 Features
- Relational Persistence: Store your materialized views in SQL databases, enabling complex querying, filtering, and reporting capabilities outside of the event loop.
- Optimistic Concurrency: Leverages EF Core's native concurrency tokens (
RowVersion/Timestamp) to prevent data overwrite during concurrent updates. - Change Tracking: Efficiently updates only modified fields using EF Core's change tracker.
- Automatic Conventions: Includes helper methods to automatically configure Tyto types (like
ProjectableVersion) within your DbContext.
📦 Installation
dotnet add package Tyto.Materializer.EntityFrameworkCore
⚡ Usage
Using this provider involves two steps: configuring your DbContext correctly and enabling the provider in your application startup.
1. Configure Your DbContext
Your EF Core DbContext must be configured to map your view entity. This includes defining a Primary Key and a Concurrency Token.
using Microsoft.EntityFrameworkCore;
using Tyto.Materializer;
using Tyto.Materializer.EntityFrameworkCore; // Required for conventions
public class MyAppContext : DbContext
{
public DbSet<UserBalanceView> UserBalances { get; set; }
public MyAppContext(DbContextOptions<MyAppContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 1. Apply Tyto conventions
// This automatically configures value converters for types like ProjectableVersion.
modelBuilder.ApplyTytoMaterializerConventions();
var view = modelBuilder.Entity<UserBalanceView>();
// 2. CRITICAL: Define the primary key.
// This property MUST match the key defined in .IdentifiedAs(...) configuration.
// If they don't match, the provider will throw a safety exception at runtime.
view.HasKey(v => v.UserId);
// 3. CRITICAL: Configure the 'Version' property as a concurrency token.
// This tells EF Core to include this column in the WHERE clause during updates
// (e.g., UPDATE ... WHERE Id = x AND Version = y).
view.Property(v => v.Version).IsConcurrencyToken();
}
}
2. Register in Program.cs
Configure Tyto to use the EF Core provider for your specific view.
var builder = WebApplication.CreateBuilder(args);
// Standard EF Core Registration
builder.Services.AddDbContext<MyAppContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
// Tyto Configuration
builder.Services.AddTytoConfiguration(tyto =>
{
tyto.AddMaterializer(materializer =>
{
materializer.ForView<UserBalanceView>()
.IdentifiedAs<Guid>(c => c.From<UserCreated>(e => e.UserId))
// Configure Storage
// Parameters: <TDbContext, TView, TKey>
.Store.UseEntityFrameworkCore<MyAppContext, UserBalanceView, Guid>();
// Note: This replaces any previously configured store for this view.
});
});
🔧 How It Works Internally
Runtime Validation
When the application starts, the EntityFrameworkCoreViewStore performs a safety check. It inspects your DbContext metadata to ensure:
- The
TViewentity is registered in the context. - A Primary Key is defined and matches the key type expected by Tyto.
- The
Versionproperty is explicitly configured as a Concurrency Token.
If any of these checks fail, it throws an InvalidOperationException immediately, preventing silent data consistency bugs.
Concurrency Handling
- Read: Uses
DbSet<T>.FindAsyncto load the entity. - Write:
- The
SaveAsyncmethod attaches the entity and sets the state toModified. - It increments the
Versionproperty in memory. - It calls
SaveChangesAsync. - EF Core generates an SQL statement like:
UPDATE Views SET Bal = 100, Version = 2 WHERE Id = 1 AND Version = 1. - If no rows are affected (meaning the version in DB was not 1), EF Core throws
DbUpdateConcurrencyException.
- The
- Retry: This provider catches that exception and re-throws it as a
Tyto...ConcurrencyException, which triggers the core library's automatic retry policy (Reload → Re-project → Save).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.0)
- Tyto.Materializer (>= 0.0.1-alpha.47)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-alpha.47 | 46 | 2/26/2026 |
| 0.0.1-alpha.46 | 45 | 2/22/2026 |
| 0.0.1-alpha.45 | 49 | 2/21/2026 |
| 0.0.1-alpha.44 | 50 | 2/21/2026 |
| 0.0.1-alpha.43 | 43 | 2/21/2026 |
| 0.0.1-alpha.42 | 50 | 2/20/2026 |
| 0.0.1-alpha.41 | 44 | 2/20/2026 |
| 0.0.1-alpha.40 | 47 | 2/20/2026 |
| 0.0.1-alpha.39 | 47 | 2/16/2026 |
| 0.0.1-alpha.38 | 46 | 2/15/2026 |
| 0.0.1-alpha.37 | 52 | 2/15/2026 |
| 0.0.1-alpha.36 | 49 | 2/15/2026 |
| 0.0.1-alpha.35 | 47 | 2/11/2026 |
| 0.0.1-alpha.34 | 44 | 2/11/2026 |
| 0.0.1-alpha.33 | 50 | 2/7/2026 |
| 0.0.1-alpha.32 | 51 | 1/26/2026 |
| 0.0.1-alpha.31 | 49 | 1/20/2026 |
| 0.0.1-alpha.30 | 51 | 1/17/2026 |
| 0.0.1-alpha.29 | 51 | 1/17/2026 |
| 0.0.1-alpha.28 | 50 | 1/14/2026 |