Reputation: 8805
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
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 float
s 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