使用实体框架4.3.1保存值时,小数位数不正确

时间:2014-03-11 16:26:48

标签: c# sql-server entity-framework decimal

不要问我为什么,但在这个遗留系统中,它将数据库字段(SQL Server 2008)设置为decimal(7,0) (nullable).

现在在EF4.3.1中我将1360的值放入实体中(在我保存之前在调试器中很好)并保存,此时我得到一个超出范围的错误:

An error occurred while updating the entries. See the inner exception for details.

内部异常解释:

Parameter value '1360.0000' is out of range.

额外的四位小数(超出范围)来自哪里?

P.S。堆栈跟踪它的价值:

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)

以下是一些代码:

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();
}

如前所述,如果coil.Width是3位数,例如726它保存得很好,但是如果coil.Width是1360我得到上述超出范围误差。

P.S。 Stock.Width和coil.Width都是可以为零的小数,即十进制?

更新:此外,我刚刚测试了将coil.Width更改为int并且如果通过1360则可以正常工作,它可以保存并且不会出现错误...嗯

2 个答案:

答案 0 :(得分:2)

解决了愚蠢的事情......

正在使用

string widthResult = "1360.0000" // The result of an edi read was giving this string.

decimal width = 0.0M;
decimal.TryParse(widthResult, out width);

TryParse的结果实际上是1360,而不是1360.0000。

添加

return decimal.Round(width, 0);

而不是仅返回小数

return width;

它运作正常,有多奇怪?!?!?!?!?!?

答案 1 :(得分:0)

我不知道您是否首先使用代码。 但是,如果您使用DecimalPropertyConfirugation类来定义小数精度。

public class MyContext : DbContext
{
    public DbSet<MyClass> MyClass;
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyClass>().Property(x => x.MyDecimalProperty).HasPrecision(7, 0);
    }
}

首先在数据库上,您可能希望重新生成EDMX文件,因为元数据应该定义正确的小数值。

在模型中,首先要确保设置适当的精度。