Forward warning #0: upgrading to EF core is not an option in the near future.
Forward warning #1: I can't change the column type to bit
because this could potentially break legacy VB apps that employ the very same db I'm developing a new app for.
Forward warning #2: I also can't employ the int
property ==> hidden bool property approach because the very same model needs to work when targeting an Oracle database (in Oracle decimal(1,0)
does indeed get mapped to bool
without issues - I need to make the same thing happen in SQL Server).
Let's assume we have a simple table like this one:
CREATE TABLE FOOBAR
(
FB_ID NUMERIC(11,0) PRIMARY KEY,
FB_YN NUMERIC(1,0) NOT NULL
);
INSERT INTO FOOBAR (FB_ID, FB_YN)
VALUES (1, 1), (2, 0);
A simple poco class:
public class FOOBAR
{
public long FB_ID {get; set;}
// [Column(TypeName = "numeric(1,0)")]
// ^--- doesn't work in ef6 => 'The store type 'numeric(1,0)' could not be found in the SQL Server provider manifest'
// ^--- allegedly this works in EF core with Microsoft.EntityFrameworkCore.Relational nuget package installed
// ^--- https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-types
// ^--- but I couldn't find anything similar for EF 6
public bool FB_YN {get; set;}
}
And an equally simple fluent config class:
public class FOOBAR_FluentConfiguration : EntityTypeConfiguration<FOOBAR>
{
public FOOBAR_FluentConfiguration()
{
ToTable(tableName: "FOOBAR");
HasKey(x => x.FB_ID);
// Property(x => x.FB_YN).HasColumnType("numeric(1,0)");
// ^--- doesn't work in ef6 => 'The store type 'numeric(1,0)' could not be found in the SQL Server provider manifest'
// ^--- allegedly this works in EF core with Microsoft.EntityFrameworkCore.Relational nuget package installed
// ^--- but I couldn't find anything similar for EF 6
}
}
As mentioned in the comments any of the attempt to convince ef6 to map <bool>
to the <numeric(1,0)>
column in table fail miserably at runtime. I have also tried achieving the desired effect via EF conventions:
public sealed class MsSqlConventions : Convention
{
public MsSqlConventions()
{
Properties<bool>().Configure(p => p.HasColumnType("numeric(1,0)")); //fails
}
}
This fails with the following message:
The store type 'numeric(1,0)' could not be found in the SQL Server provider manifest
While this one:
public sealed class MsSqlConventions : Convention
{
public MsSqlConventions()
{
Properties<bool>().Configure(p => p.HasColumnType("numeric").HasPrecision(1, 0)); //fails
}
}
This fails with the following message:
Precision and scale have been configured for property 'FB_YN'. Precision and scale can only be configured for Decimal properties.
I also tried to toy around with (enrich) the SQL Server provider manifest a la:
DbProviderServices.GetProviderManifest();
but I can't make heads or tails out of it (yet). Any insights appreciated.
Here's a way to arm-twist EF6 into handling numeric(1,0) columns as BIT columns. It's not the best thing ever and I've only tested it in the scenarios shown at the bottom but it works reliably as far as my testing goes. If someone detects a corner case where things do not go as planned feel free to drop a comment and I will improve upon this approach:
And the implementation of the interceptor:
And some quick testing: