Civitas.Id.Sweden.EntityFrameworkCore 1.0.0

dotnet add package Civitas.Id.Sweden.EntityFrameworkCore --version 1.0.0
                    
NuGet\Install-Package Civitas.Id.Sweden.EntityFrameworkCore -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Civitas.Id.Sweden.EntityFrameworkCore" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Civitas.Id.Sweden.EntityFrameworkCore" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Civitas.Id.Sweden.EntityFrameworkCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Civitas.Id.Sweden.EntityFrameworkCore --version 1.0.0
                    
#r "nuget: Civitas.Id.Sweden.EntityFrameworkCore, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Civitas.Id.Sweden.EntityFrameworkCore@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Civitas.Id.Sweden.EntityFrameworkCore&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Civitas.Id.Sweden.EntityFrameworkCore&version=1.0.0
                    
Install as a Cake Tool

Civitas.Id.Sweden.EntityFrameworkCore

EF Core 10 ValueConverters for the Civitas.Id.Sweden Swedish official-ID types.

Install

dotnet add package Civitas.Id.Sweden.EntityFrameworkCore

Wire it once

using Civitas.Id.Sweden.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

public sealed class AppDbContext : DbContext
{
    protected override void ConfigureConventions(ModelConfigurationBuilder builder)
        => builder.UseCivitasIdSweden();
}

That's it. Now your entities can use the domain types directly:

public sealed class Customer
{
    public Guid Id { get; init; }
    public PersonalId TaxpayerId { get; set; } = null!;
    public CoordinationId? OptionalCoordinationId { get; set; }
}

public sealed class Company
{
    public Guid Id { get; init; }
    public OrganisationId OrgId { get; set; } = null!;
}

Storage shape

Type DDL (SQL Server) DDL (Postgres) DDL (SQLite) Notes
PersonalId char(12) NOT NULL character(12) NOT NULL TEXT NOT NULL Always 12 digits.
CoordinationId char(12) NOT NULL character(12) NOT NULL TEXT NOT NULL Always 12 digits.
OrganisationId varchar(12) NOT NULL character varying(12) NOT NULL TEXT NOT NULL Variable width: 10 digits for legal-person, 12 for Enskild firma. Do NOT add CHECK(LEN = 12).

LINQ queries

Equality and IN-clause queries translate to SQL natively:

var id = PersonalId.Parse("189001019802");
var customer = await db.Customers.SingleAsync(c => c.TaxpayerId == id);

var batch = new[] { id1, id2, id3 };
var matches = await db.Customers.Where(c => batch.Contains(c.TaxpayerId)).ToListAsync();

Member access on the converted value (c.TaxpayerId.GetAge(today)) does NOT translate — EF backlog #35515. Workaround: denormalise the value to a shadow column at write time.

Polymorphic SwedishOfficialId column

Not supported in v1.0. If your entity has a column that could hold any of the three subtypes (audit log subject, KYC record), store it as a raw string and parse on read:

public sealed class AuditLog
{
    public Guid Id { get; init; }
    public string SubjectId { get; set; } = null!;  // raw canonical string
}

// Read:
var subject = SwedishOfficialId.ParseAny(log.SubjectId);

OrganisationForm queries

Form is a runtime property derived from the digits, not a stored column. If you frequently filter by form (WHERE company.OrgId.Form == OrganisationForm.AktiebolagOvriga), denormalise:

public sealed class Company
{
    public Guid Id { get; init; }
    public OrganisationId OrgId { get; set; } = null!;
    public OrganisationForm Form { get; set; }  // populate in your code
}

MySQL / MariaDB collation note

With unicode: false, the Pomelo MySQL provider may emit CHARACTER SET ascii or latin1. If your server's default collation is utf8mb4, joins between an OrgId column and a utf8mb4 column may raise collation-mismatch errors. Override per-property if needed:

modelBuilder.Entity<Company>()
    .Property(c => c.OrgId)
    .UseCollation("utf8mb4_bin");

Migration from existing string columns

If your column already stores the library's canonical form (12-digit for PersonalId/CoordinationId, 10-digit for legal-person OrganisationId, 12-digit for Enskild firma) — no migration needed. Add the converter and the column just starts being parsed/formatted automatically.

If your column stores a different format (hyphenated short, "16"-prefixed 12-digit, etc.) — write a one-off migrationBuilder.Sql to normalise before adding the converter.

Corrupted DB row handling

If a stored row contains a malformed Civitas ID string (e.g. from a legacy data migration, off-path writer, or DB corruption), EF Core's materialiser will throw InvalidIdNumberException (from Civitas.Id.Sweden.Errors) when the property is read.

The exception's Input property is REDACTED by design — the raw rejected string is never carried in the exception chain. However, callers MUST NOT log Exception.ToString() on EF exceptions that may surface this for paths touching Civitas ID columns, because the call stack may still leak field names that imply PII presence. Log structured fields (ex.GetType().Name, ex.Message) instead.

AOT

The core Civitas.Id.Sweden library is IsAotCompatible=true. This companion package is NOT — EF Core 10's NativeAOT support is documented as experimental upstream. Stable AOT is informally targeted for EF Core 12. We will adopt IsAotCompatible=true when EF makes it production-ready.

Advanced wiring — scaffolded DbContexts

For consumers who can't override ConfigureConventions (e.g. scaffolded contexts that regeneration would overwrite), register per-property:

modelBuilder.Entity<Customer>()
    .Property(c => c.TaxpayerId)
    .HasConversion(new PersonalIdConverter());
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.0.0 114 6/20/2026

See CHANGELOG.md for the full release notes.