Reputation: 9725
Don't ask me why but in this legacy system it has a database field (SQL Server 2008) set as decimal(7,0) (nullable).
Now in EF4.3.1 I'm putting a value of 1360 into the entity (fine in debugger until I save) and saving, at which point I get an out of range error:
An error occurred while updating the entries. See the inner exception for details.
The inner exception explains:
Parameter value '1360.0000' is out of range.
Where has the extra four decimal places (that take it out of range) come from ?
P.S. The stack trace for what it's worth:
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
Here's some code:
TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable });
using (scope)
{
using (WEDFUTEntities ctx = new WEDFUTEntities())
{
ctx.Connection.Open();
Stock newStock = new Stock
{
Width = coil.Width,
};
ctx.Stocks.AddObject(newStock);
ctx.SaveChanges();
ctx.Connection.Close();
}
scope.Complete();
}
As stated before if the coil.Width is 3 digits, e.g. 726 it saves fine, however if the coil.Width is 1360 i get the aforementioned out of range error.
P.S. Both the Stock.Width and coil.Width are nullable decimals, i.e. decimal?
Update: Additionally I just tested changing coil.Width to be an int and it then works if passing 1360, it saves and throws no errors... hmmm
Upvotes: 2
Views: 2592
Reputation: 9725
Solved the stupid thing...
Was using
string widthResult = "1360.0000" // The result of an edi read was giving this string.
decimal width = 0.0M;
decimal.TryParse(widthResult, out width);
The result of the TryParse was in fact 1360, not 1360.0000.
By adding
return decimal.Round(width, 0);
instead of just returning the decimal width
return width;
It works fine, how odd is that ?!?!?!?!?!?
Upvotes: 2
Reputation: 1125
I don't know if you are using code first or not. However if you are you can use the DecimalPropertyConfirugation class to define the decimal precision.
public class MyContext : DbContext
{
public DbSet<MyClass> MyClass;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyClass>().Property(x => x.MyDecimalProperty).HasPrecision(7, 0);
}
}
On database first you might want to regenerate the EDMX file as the metadata should define the proper decimal value.
In Model first be sure to set the appropriate precision as well.
Upvotes: 0