This package provides Entity Framework Core extensions and value converters to persist the PosInformatique.Foundations.People value objects:
FirstNamestored asNVARCHAR(50)with proper conversion and comparisons.LastNamestored asNVARCHAR(50)with proper conversion and comparisons.
It exposes fluent configuration helpers to simplify mapping in your DbContext model configuration.
You can install the package from NuGet:
dotnet add package PosInformatique.Foundations.People.EntityFrameworkThis package depends on the base package PosInformatique.Foundations.People.
- Provides an extension method
IsFirstName()andIsLastName()to configure EF Core properties forFirstNameandLastName. - Easy EF Core mapping for
FirstNameandLastNameproperties. - Maps to NVARCHAR(50), Unicode, non-fixed-length columns.
- Built on top of the core
FirstNameandFirstNamevalue objects. - Keeps domain normalization rules in the database boundary.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using PosInformatique.Foundations.People;
public sealed class PersonEntity
{
public int Id { get; set; }
// Persisted as NVARCHAR(50) using the FirstName converter and comparer
public FirstName FirstName { get; set; } = null!;
// Persisted as NVARCHAR(50) using the LastName converter and comparer
public LastName LastName { get; set; } = null!;
}
public sealed class PeopleDbContext : DbContext
{
public DbSet<PersonEntity> People => Set<PersonEntity>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var person = modelBuilder.Entity<PersonEntity>();
person.HasKey(p => p.Id);
// Configure FirstName as NVARCHAR(50) with conversions
person.Property(p => p.FirstName)
.IsFirstName();
// Configure LastName as NVARCHAR(50) with conversions
person.Property(p => p.LastName)
.IsLastName();
}
}This will configure:
- The
FirstNameproperty of thePersonEntityentity with:NVARCHAR(50)(Unicode) column length
- The
LastNameproperty of thePersonEntityentity with:NVARCHAR(50)(Unicode) column length
var options = new DbContextOptionsBuilder<PeopleDbContext>()
.UseSqlServer(connectionString)
.Options;
using var db = new PeopleDbContext(options);
// Insert
var person = new PersonEntity
{
FirstName = FirstName.Create("jean-paul"), // normalized to "Jean-Paul"
LastName = LastName.Create("dupont") // normalized to "DUPONT"
};
db.Add(person);
await db.SaveChangesAsync();
// Query (comparison and ordering use normalized string values via comparer/converter)
var ordered = await db.People
.OrderBy(p => p.LastName) // "DUPONT" etc.
.ThenBy(p => p.FirstName) // "Jean-Paul" etc.
.ToListAsync();public sealed class PersonEntityConfiguration : IEntityTypeConfiguration<PersonEntity>
{
public void Configure(EntityTypeBuilder<PersonEntity> builder)
{
builder.HasKey(p => p.Id);
builder.Property(p => p.FirstName)
.IsFirstName();
builder.Property(p => p.LastName)
.IsLastName();
}
}
public sealed class PeopleDbContext : DbContext
{
public DbSet<PersonEntity> People => Set<PersonEntity>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new PersonEntityConfiguration());
}
}- The mapping enforces the maximum length defined by the domain (
FirstName.MaxLengthandLastName.MaxLength), ensuring alignment between code and database. - Converters/Comparers guarantee consistent persistence and querying semantics with the normalized value objects.