0

I'm using the Entity framework (6.1.3) (database first) for one of my projects where I have three tables in the database which contains decimal fields.

The decimal fields are set with a precision of 18 and a scale of 5, like this: decimal(18, 5)

I have checked the edmx XML file and it seems like the decimals are mapped as they should. I.e.:

<Property Name="Price" Type="decimal" Precision="18" Scale="5" Nullable="false" />

However, when I try to save a calculated decimal value which looks like, i.e. 28021.800000000000000000000002, I get an exception telling me that the property value is out of range.

Shouldn't entity framework just save the precision and scaled value of this decimal? If not, how exactly do I make my decimal "valid"?

Thanks in advance :-)

Edited with code sample:

// Loop through billing price lines on this billing
foreach (BillingPriceLine priceLine in billing.BillingPriceLines)
{
      // Price line specification sum fields
      decimal totalPriceLineSpecificationProduction = 0;
      decimal totalPriceLineSpecificationSum = 0;

      // Loop through billing price line specifications on this price line
      foreach (BillingPriceLineSpecification specification in priceLine.BillingPriceLineSpecifications)
      {
            // First, check if the estimated production and realised production has a value
            if (specification.EstimatedProduction.HasValue && specification.RealisedProduction.HasValue)
            {
                  // Calculate production for a price line specification
                  specification.Production = specification.EstimatedProduction.Value - specification.RealisedProduction.Value;

                  // Add production to total price line specification production
                  totalPriceLineSpecificationProduction = specification.Production;

                   // Add to total price line specification sum
                   totalPriceLineSpecificationSum += specification.Production * specification.Price;
              }
        }

        // Set total production on price line
        priceLine.Production = totalPriceLineSpecificationSum;

        // Set price on price line
        priceLine.Price = totalPriceLineSpecificationProduction / priceLine.Production;

         // Set total price on price line
         priceLine.TotalPrice = (priceLine.Production * priceLine.Price) * 100;
  }

  // Set subtotal, VAT and total sum on billing
  billing.Subtotal = billing.BillingPriceLines.Sum(x => x.TotalPrice);
  billing.VAT = billing.Subtotal / 4;
  billing.Total = billing.Subtotal + billing.VAT;

  // Save changes in database
  return ctx.SaveChanges() > 0;
Bo Mortensen
  • 935
  • 1
  • 13
  • 31
  • possible duplicate of [Decimal precision and scale in EF Code First](http://stackoverflow.com/questions/3504660/decimal-precision-and-scale-in-ef-code-first) - the method used here is the same, you just need to override the OnModelCreating. – user1666620 Jun 29 '15 at 09:53
  • I've tried using the modelBuilder, but it gets ignored it seems. Like so: `modelBuilder.Entity().Property(x => x.Price).HasPrecision(18, 5);` – Bo Mortensen Jun 29 '15 at 09:55
  • are you doing it in the right place in the model? can you add the code sample of where you have added that code to the question? – user1666620 Jun 29 '15 at 10:07
  • I think EF (or sql server) will automatically truncate decimal values to fit in the defined scale. – Hamid Pourjam Jun 29 '15 at 10:11
  • 3
    just realised that the number you provided, `28021.800000000000000000000002`, has more than 5 decimal places... `decimal(18,5)` means that the decimal has 18 total digits, 5 of which are after the decimal place. http://stackoverflow.com/questions/18874410/decimal-out-of-range – user1666620 Jun 29 '15 at 10:25
  • Thought that entity framework only took the 5 digits after the decimal place automatically. So, how exactly do I take only the 5 digits after the decimal place? I'm not allowed to round anything here. `String.Format` seems a bit like a dirty hack here, no? :-) – Bo Mortensen Jun 29 '15 at 10:55
  • @BoMortensen Seems like `totalPriceLineSpecificationProduction / priceLine.Production` cannot be exactly divided. If rounding is not an option, can you increase precision and scale of database field to C# max? Like `decimal(29, 20)` – ranquild Jun 29 '15 at 12:17
  • @AlexPolyankin yup, I just did that and it works ;-) Thanks a lot ! – Bo Mortensen Jun 29 '15 at 12:26

1 Answers1

0

If rounding is not an option, you can increase precision and scale of database field to C# max (28-29 as in docs). Like decimal(29, 20).

ranquild
  • 1,799
  • 1
  • 16
  • 25