Feature Proposal: Domain-Based CLR Type Mapping (Opt-In)
Background
We’re currently migrating a production system from LCPI IBProvider (OleDb) to FirebirdSql.Data.FirebirdClient.
Our database makes heavy use of user-defined domains, for example:
SMALLINT + CHECK → used as Boolean
CHAR(16) CHARACTER SET OCTETS → used as Guid
With IBProvider, this works very nicely:
- It looks at
RDB$FIELD_SOURCE
- Automatically maps domains to the correct CLR types (
bool, Guid)
With the current .NET provider:
This breaks quite a lot of things for us — especially data-binding and comparisons.
Real-World Situation
Our system is not small:
- 300+ tables
- Heavy use of Typed DataSet (ADO.NET)
Because of that, fixing this manually isn’t really an option:
- Changing generated DataSet types doesn’t scale
- Regeneration overwrites everything
- Maintaining custom mappings across hundreds of tables is fragile
- Adding a separate mapping layer would mean large refactoring
In short, without something at the provider level, migration becomes very difficult.
Why We’re Proposing This Upstream
We already implemented this on our side and it works well.
However, keeping it as a private fork is painful:
- We constantly need to rebase against upstream
- It adds maintenance overhead
- There’s always a risk of falling behind
By contributing this upstream:
- Others with similar domain-based schemas can benefit
- We don’t need to maintain a long-lived fork
- The feature can evolve together with the provider
Proposal
Add an opt-in domain-based mapping, configured via connection string.
Example:
boolean domains=D_BOOL%,IS\_%
guid domains=D_GUID%
How it works:
-
Patterns use SQL LIKE syntax (%, _, \_)
-
We match against RDB$FIELD_SOURCE
-
If matched:
- Boolean domains → returned as
bool
- Guid domains → returned as
Guid
Important:
- The underlying data does not change
(SMALLINT and CHAR(16) are still read/written as-is)
- This only affects the reported ADO.NET type
- Completely opt-in — no impact unless configured
Implementation
We already have a working implementation:
-
DomainPatternList
Handles LIKE-style pattern matching (case-insensitive, ignores RDB$*)
-
DomainNameResolver
Resolves and caches domain names per connection
-
DbField changes
RawDbDataType → actual wire type
OverrideDataType → exposed type
-
Connection string support
BooleanDomains
GuidDomains
Real Usage
We’re already using this internally and it made a big difference:
- Restores IBProvider-like behavior
- Removes the need for manual conversions
- Fixes data-binding and comparison issues
- Makes the migration manageable without large refactoring
Testing
- 12 integration tests
- Unit tests for pattern matching and parsing
- All existing tests pass
Compatibility
- No breaking changes
- Fully backward compatible
- Feature is strictly opt-in
Notes
We know the contribution guidelines suggest discussing first — that’s why we’re opening this before a PR.
We’re happy to adjust the design based on feedback.
Additional Context
We plan to keep using this provider long-term and are also open to becoming a project sponsor.
Feature Proposal: Domain-Based CLR Type Mapping (Opt-In)
Background
We’re currently migrating a production system from
LCPI IBProvider (OleDb)toFirebirdSql.Data.FirebirdClient.Our database makes heavy use of user-defined domains, for example:
SMALLINT+ CHECK → used as BooleanCHAR(16) CHARACTER SET OCTETS→ used as GuidWith IBProvider, this works very nicely:
RDB$FIELD_SOURCEbool,Guid)With the current .NET provider:
Domain information is ignored
We get:
SMALLINT→Int16CHAR(16)→byte[]This breaks quite a lot of things for us — especially data-binding and comparisons.
Real-World Situation
Our system is not small:
Because of that, fixing this manually isn’t really an option:
In short, without something at the provider level, migration becomes very difficult.
Why We’re Proposing This Upstream
We already implemented this on our side and it works well.
However, keeping it as a private fork is painful:
By contributing this upstream:
Proposal
Add an opt-in domain-based mapping, configured via connection string.
Example:
How it works:
Patterns use SQL LIKE syntax (
%,_,\_)We match against
RDB$FIELD_SOURCEIf matched:
boolGuidImportant:
(
SMALLINTandCHAR(16)are still read/written as-is)Implementation
We already have a working implementation:
DomainPatternList
Handles LIKE-style pattern matching (case-insensitive, ignores
RDB$*)DomainNameResolver
Resolves and caches domain names per connection
DbField changes
RawDbDataType→ actual wire typeOverrideDataType→ exposed typeConnection string support
BooleanDomainsGuidDomainsReal Usage
We’re already using this internally and it made a big difference:
Testing
Compatibility
Notes
We know the contribution guidelines suggest discussing first — that’s why we’re opening this before a PR.
We’re happy to adjust the design based on feedback.
Additional Context
We plan to keep using this provider long-term and are also open to becoming a project sponsor.