0

I have used the EF Power Tool to reverse engineer a database table with a decimal field that has a precision of (18,4).

But, the precision of the decimal inserts are rounded to 2 decimal places.

There is a post on CodePlex that seems to say the bug is fixed. (https://entityframework.codeplex.com/workitem/734)

But, I am still seeing the problem. I have downloaded the latest version of the Power Tools and I have made sure to be using Entity Framework 6.1.0.

If I alter the mapping code (see below), I can get the precision I need.

this.Property(t => t.G_KWH).HasColumnName("G_KWH").HasPrecision(18,4);

But, the next time I reverse engineer the database my mapping code edit will be removed.

Maybe I am doing something wrong. Maybe the bug is not really fixed. Maybe you can help provide me with a work-around that will not get copied over if I reverse engineer the database again.

Any help would be appreciated.

My Table:

CREATE TABLE [dbo].[ConvertCarb](
    [ConvertCarbID] [int] IDENTITY(1,1) NOT NULL,
    [CountryID] [int] NULL,
    [StateProvID] [int] NULL,
    [KWH_FT2] [float] NULL,
    [G_KWH] [decimal](18, 4) NULL,
    [NatGas_GJ_M2] [float] NULL,
    [FuelOil_GJ_M2] [float] NULL,
 CONSTRAINT [PK_ConvertCarb] PRIMARY KEY CLUSTERED 
(
    [ConvertCarbID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[ConvertCarb]  WITH NOCHECK ADD  CONSTRAINT [FK_ConvertCarb_Countries] FOREIGN KEY([CountryID])
REFERENCES [dbo].[Countries] ([CountryID])
GO

ALTER TABLE [dbo].[ConvertCarb] NOCHECK CONSTRAINT [FK_ConvertCarb_Countries]
GO

ALTER TABLE [dbo].[ConvertCarb]  WITH NOCHECK ADD  CONSTRAINT [FK_ConvertCarb_StateProvinces] FOREIGN KEY([StateProvID])
REFERENCES [dbo].[StateProvinces] ([StateProvID])
GO

ALTER TABLE [dbo].[ConvertCarb] NOCHECK CONSTRAINT [FK_ConvertCarb_StateProvinces]
GO

Run-time Code:

 CarbonContext db = new CarbonContext();

 var convertCarb = new ConvertCarb();
 convertCarb.CountryID = 164;
 convertCarb.StateProvID = null;
 convertCarb.KWH_FT2 = 0;
 convertCarb.G_KWH = Decimal.Parse("0.1234");
 convertCarb.NatGas_GJ_M2 = 0;
 convertCarb.FuelOil_GJ_M2 = 0;
 db.ConvertCarbs.Add(convertCarb);
 db.SaveChanges();

Mapping:

public class ConvertCarbMap : EntityTypeConfiguration<ConvertCarb>
{
    public ConvertCarbMap()
    {
        // Primary Key
        this.HasKey(t => t.ConvertCarbID);

        // Properties
        // Table & Column Mappings
        this.ToTable("ConvertCarb");
        this.Property(t => t.ConvertCarbID).HasColumnName("ConvertCarbID");
        this.Property(t => t.CountryID).HasColumnName("CountryID");
        this.Property(t => t.StateProvID).HasColumnName("StateProvID");
        this.Property(t => t.KWH_FT2).HasColumnName("KWH_FT2");
        this.Property(t => t.G_KWH).HasColumnName("G_KWH");
        this.Property(t => t.NatGas_GJ_M2).HasColumnName("NatGas_GJ_M2");
        this.Property(t => t.FuelOil_GJ_M2).HasColumnName("FuelOil_GJ_M2");

        // Relationships
        this.HasOptional(t => t.Country)
            .WithMany(t => t.ConvertCarbs)
            .HasForeignKey(d => d.CountryID);
        this.HasOptional(t => t.StateProvince)
            .WithMany(t => t.ConvertCarbs)
            .HasForeignKey(d => d.StateProvID);

    }
}
ADH
  • 2,971
  • 6
  • 34
  • 53

2 Answers2

1

The solution I found to this problem was based off Decimal precision and scale in EF Code First.

Effectively, the above solution involves adding your precision information into the OnModelCreating function of your database context. This will work, but as you mentioned, the problem with this is that using "Reverse Engineer Code First" will erase the precision information.

To remedy this, I elected to create a new context class that inherited from the original context class:

public partial class OriginalContext : DbContext
{
    ...
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        ...
        // This would be overwritten if we left it in the OriginalContext class
        // modelBuilder.Entity<ConvertCarb>().Property(x => x.G_KWH).HasPrecision(18, 4);
    }
}

public class ExtendedContext : OriginalContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Put the code here instead so it isn't overwritten when we reverse engineer
        modelBuilder.Entity<ConvertCarb>().Property(x => x.G_KWH).HasPrecision(18, 4);
    }
}

When I need a context object, I can now use the ExtendedContext one. This gives the proper precision without the concern about it being overwritten should the underlying database change.

Community
  • 1
  • 1
LRP
  • 20
  • 4
0

When I have this issue EF 6.1.0 and PT 0.9.0.0 I corrected the mapping manually.

I recommend you same.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
Major
  • 1