EntityMatcher 1.0.0
dotnet add package EntityMatcher --version 1.0.0
NuGet\Install-Package EntityMatcher -Version 1.0.0
<PackageReference Include="EntityMatcher" Version="1.0.0" />
<PackageVersion Include="EntityMatcher" Version="1.0.0" />
<PackageReference Include="EntityMatcher" />
paket add EntityMatcher --version 1.0.0
#r "nuget: EntityMatcher, 1.0.0"
#:package EntityMatcher@1.0.0
#addin nuget:?package=EntityMatcher&version=1.0.0
#tool nuget:?package=EntityMatcher&version=1.0.0
EntityMatcher
A .NET library for deterministic, offline entity matching across domains. Compares names, addresses, phones, dates, organizations, countries, and arbitrary text/numeric fields using alias resolution, fuzzy scoring, and tolerance-based matching. Supports single-pair comparison, record-level profile matching, and high-performance set matching.
Features
- 12 domain matchers: GivenName, FamilyName, TitleOrCredential, OrganizationName, USStreetAddress, USStateTerritory, Country, Phone, Date, Exact, Text, Numeric
- Alias resolution: 278 given-name groups (947 names), 249 ISO 3166 countries, 62 US states/territories, 32 title/credential groups, 200+ USPS suffix/unit mappings
- Fuzzy scoring: Jaro-Winkler, Damerau-Levenshtein, token-set similarity
- Tolerance matching: Date (configurable day window), Numeric (absolute or percentage)
- Record-level profiles: Required/Optional/Veto field semantics with weighted scoring
- Set matching (net8.0+): Ad-hoc lookup, 1:1 enrollment comparison, 1:many matching, hybrid exact+fuzzy, confidence-ranked pool matching
- Custom matchers: Extensible via
IFieldMatcher-- add your own domain-specific comparison logic - Zero runtime dependencies: Core package targets
netstandard2.0, no I/O, no reflection, no network calls - Thread-safe: Immutable engine, concurrent-safe set matcher
Quick Start
using EntityMatcher.Core;
// Build an engine (loads compiled-in alias data automatically)
var engine = new EntityMatcherEngineBuilder().Build();
// Compare individual fields
var result = engine.Compare(FieldKind.GivenName, "Bill", "William");
// result.State == Match, Method == Alias, Score == 100
// Fuzzy text matching
engine.Compare(FieldKind.Text, "Accounting", "Acounting");
// Match via Jaro-Winkler fuzzy, score ~97
// Numeric with tolerance
engine.Compare(FieldKind.Numeric, "$99.99", "$100.00",
new MatchOptions { NumericTolerance = 0.05m });
// Match via tolerance scoring
Record-Level Matching
using EntityMatcher.Profiles;
var profile = new MatchProfile<Person>()
.Require(p => p.LastName, FieldKind.FamilyName)
.Optional(p => p.FirstName, FieldKind.GivenName, weight: 2m)
.Optional(p => p.DOB, FieldKind.Date, weight: 1m)
.Veto(p => p.SSN, FieldKind.Exact)
.Threshold(85);
var result = profile.Compare(personA, personB, engine);
// result.IsMatch, result.Score, result.Confidence
// result.Explain() for human-readable breakdown
Set Matching (net8.0+)
using EntityMatcher.SetMatching;
// Build a set matcher for batch operations
var matcher = new EntitySetMatcher<Person, PersonMatchType>(
databaseRecords, matchDefinitions);
// Ad-hoc lookup against a set
var matches = matcher.FindMatches(incomingRecord, [PersonMatchType.Ssn]);
// 1:1 enrollment comparison with tiered criteria
var result = matcher.CreateTwoWayMatchDictionary(
enrollmentB,
tieredCriteria: [[PersonMatchType.Ssn], [PersonMatchType.Name, PersonMatchType.Dob]]);
// 1:many matching (customer to orders)
var multi = matcher.CreateMultiMatchResult(orders, [PersonMatchType.CustomerId]);
// Confidence-ranked pool matching (best matches assigned first, pool drains top-down)
var ranked = matcher.CreateRankedMatchDictionary(
enrollmentB, profile: fuzzyProfile, engine: engine,
exactCriteria: [[PersonMatchType.Ssn]]);
// Hybrid: exact dictionary pass + fuzzy profile fallback with blocking
var hybrid = matcher.CreateHybridMatchDictionary(
enrollmentB,
exactCriteria: [[PersonMatchType.Ssn]],
fuzzyProfile: fuzzyProfile,
engine: engine,
blockingStrategy: BlockingKeyStrategies.FirstCharOf<Person>(p => p.LastName));
Match Quality
Tested against 10,000 synthetic records with realistic data corruption:
| Strategy | Clean | Moderate | Dirty | Hostile |
|---|---|---|---|---|
| SSN only | 100% | 75% | 60% | 19% |
| Tiered (SSN + Name/DOB + Email) | 100% | 99% | 96% | 66% |
| Tiered + Phone | 100% | 100% | 100% | 83% |
| Hybrid (SSN + Fuzzy w/ blocking) | 100% | 99% | 97% | 91% |
| Hybrid (SSN + Email + Phone + Fuzzy) | 100% | 100% | 100% | 97% |
Projects
| Project | Target | Description |
|---|---|---|
EntityMatcher |
netstandard2.0 + net8.0 + net9.0 | Core library |
EntityMatcher.DependencyInjection |
netstandard2.0 | Optional DI companion |
EntityMatcher.UnitTests |
net10.0 | Unit + acceptance tests |
EntityMatcher.ProfileTests |
net10.0 | Profile matching tests |
EntityMatcher.RegressionTests |
net10.0 | False-positive + concurrency regression tests |
EntityMatcher.Benchmarks |
net10.0 | BenchmarkDotNet performance suite |
Data Sources
All alias data is compiled directly into C# source code (zero I/O at runtime):
- Given names: 278 groups from onyxrev/common_nickname_csv (public domain)
- Countries: 249 entries from ISO 3166-1
- US States: 62 entries (50 states + DC + territories + military codes)
- Titles/Credentials: 32 curated groups
- USPS Suffixes: 200+ entries from USPS Publication 28 (public domain)
- USPS Secondary Units: 24 entries from USPS Publication 28
Installation
dotnet add package EntityMatcher
dotnet add package EntityMatcher.DependencyInjection # optional, for DI integration
Documentation
- Getting Started -- Installation, quick start, configuration
- Field Matchers -- All 12 domain matchers with examples
- Profiles -- Record-level matching with Required/Optional/Veto fields
- Set Matching -- Batch operations, 1:1, 1:many, hybrid, ranked matching
- Custom Matchers -- Extensibility with custom field types
- Data Sources -- Embedded datasets, adding custom aliases
- Performance -- Benchmarks, quality report, optimization guidance
Building
dotnet build EntityMatcher.slnx
dotnet test EntityMatcher.slnx
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
net8.0
- System.Collections.Immutable (>= 8.0.0)
-
net9.0
- System.Collections.Immutable (>= 8.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on EntityMatcher:
| Package | Downloads |
|---|---|
|
EntityMatcher.DependencyInjection
Microsoft.Extensions.DependencyInjection integration for EntityMatcher. Registers IEntityMatcherEngine as a singleton with optional builder configuration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 157 | 4/4/2026 |