just.another.programmer
just.another.programmer

Reputation: 8805

Can I map a decimal property to a float db column

I'm writing a .NET web app on top of a existing DB app (SQL server). The original developer stored money in float columns instead of money or decimal. I really want to use Decimal inside my POCOs (especially because I will be doing further operations on the values after I get them).

Unfortunately, I cannot touch the DB schema. Is there a way to still use Decimal in my POCOs and tell EF "It's ok, I know decimal and float don't get along. I don't like it either. Just do your best."

With no special configuration, I get this error:

The specified cast from a materialized 'System.Double' type to the 'System.Decimal' type is not valid.

I tried using modelBuilder.Entity(Of myPocoType).Property(Function(x) x.MoneyProperty).HasColumnType("float"), but that gets me this error:

Schema specified is not valid. Errors:
(195,6) : error 0063: Precision facet isn't allowed for properties of type float.
(195,6) : error 0063: Scale facet isn't allowed for properties of type float.

Upvotes: 0

Views: 2567

Answers (1)

anaximander
anaximander

Reputation: 7140

Something like this would work:

public class MyPocoType
{
    public float FloatProp { get; set; }

    [NotMapped]
    public decimal DecimalProp
    {
        get
        {
            return (decimal)FloatProp;
        }
        set
        {
            FloatProp = (float)value;
        }
    }
}

EF will ignore the decimal one, but you can use it and it'll set the underlying float. You can add in your own logic for handling the loss of precision if there's anything special you want it to do, and you might need to catch the cases where the value is out of range of what it's being converted to (float has much larger range, but decimal has much greater precision).

It's not a perfect solution, but if you're stuck with floats then it's not going to get much better. A float is inherently a little fuzzy, so that's going to trip you up somewhere.

If you really want to get complex, you could look at keeping the decimal value internally and then using the various events that happen at save time (some logic in an overridden SaveChanges(), or catching the SavingChanges event perhaps) to convert to float only once, to cut down on the buildup of conversion errors.

Upvotes: 1

Related Questions