【问题标题】:argument exception parameter value is out of range decimal参数异常参数值超出范围十进制
【发布时间】:2019-03-05 09:58:01
【问题描述】:

在数据库中price 列设置为decimal(20, 2)

表示它可以保存小数点前18位和小数点后2位。对吧?

现在,当我尝试保存价值 12345678.00 时,它会显示:parameter value is out of range

我做错了什么?

更新:

123456.00 is saved in db.
1234567.00 gives exception

例外:

System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 ---> System.Data.Entity.Core.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 ---> System.ArgumentException:参数值“12345678.00”超出范围。在 System.Data.SqlClient.TdsParser.TdsExecuteRPC(SqlCommand cmd,_SqlRPC[] rpcArray,Int32 超时,布尔 inSchema,SqlNotificationRequest 通知请求,TdsParserStateObject stateO0bj,布尔 isCommandProc,布尔同步,TaskCompletionSource1 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, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 完成,Int32 超时,任务和任务, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.BeginExecuteNonQueryInternal(CommandBehavior behavior, AsyncCallback callback, Object stateObject, Int32 timeout, Boolean inRetry, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.BeginExecuteNonQueryAsync(AsyncCallback callback, Object stateObject) at System.Threading.Tasks.TaskFactory1.FromAsyncImpl(Func3 beginMethod, Func2 endFunction, Action1 endAction, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory1.FromAsync(Func3 beginMethod, Func2 endMethod,对象状态)在 System.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(CancellationToken cancelToken) --- 从先前抛出异常的位置结束堆栈跟踪---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在系统System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter1.GetResult() at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.<ExecuteAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext() --- End of inner exception stack trace --- at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d1.MoveNext() 处的 .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) - -- 从先前引发异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Data.Entity 的 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) .Core.Objects.ObjectContext.d__39.MoveNext() --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 的 System.Runtime.CompilerServices 处从先前引发异常的位置结束堆栈跟踪。 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.d__91.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesInternalAsync>d__31.MoveNext() --- End of inner exception stack trace --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() 处的 TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)

更新:

我创建了一个新数据库并运行迁移以确保 db 列正是我所期望的,它是:

完整代码:

Ad.cs:

[Table("ad")]
public class Ad
{
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None), Column("id")]
        public Guid Id { get; set; }
        [Column("price")]
        public decimal Price { get; set; }
        //other attributes
}

DbMigration 类:

public partial class added_price_to_ad : DbMigration
    {
        public override void Up()
        { 
            AddColumn("dbo.ad", "price", c => c.Decimal(nullable: false, precision: 20, scale: 2));
        }

        public override void Down()
        { 
            DropColumn("dbo.ad", "images_count");
        }
    }

AdVm.cs:

public class AdVm
    {
        public string Id { get; set; }
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = 
        "{0:#.#}")]
        public decimal Price { get; set; }
        //other attributes
    }

create.cshtml:

@model ProjectName.ViewModels.AdVm
@using (Html.BeginForm("Save", "Ads", FormMethod.Post, new { id = "CreateAdForm" }))
                    {
                        @Html.AntiForgeryToken()

                        <div class="form-horizontal">
                            @Html.ValidationSummary(true)
                            @Html.HiddenFor(x => x.Id)

<div class="form-group">
                                @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" })
                                <div class="col-md-10">
                                    @Html.EditorFor(model => model.Price)
                                    @Html.ValidationMessageFor(model => model.Price)
                                </div>
                            </div>

                        </div>
                       <input type="submit"/>
                    }

控制器:

    [HttpPost]
            [ValidateAntiForgeryToken]
    public async Task<ActionResult> Save(AdVm adVm)
   {
       var ad= Mapper.Map<AdVm, Ad>(adVm);
       db.Ads.Add(ad);
       await db.SaveChangesAsync(); //throws exception here
       return RedirectToAction("Details", new { id= ad.Id });
    }

【问题讨论】:

  • 还有其他问题..12345678.00 是十进制(20,2) 的有效值,可能是存储过程的输入变量长度有问题。
  • 错误可能是由于其他原因,因为 12345678.00 值可以存储在十进制(20, 2) 列中。尝试传递一些较低的值并查看结果。如果仍然得到较低值的错误,则将确认由于其他列导致的错误。
  • 您确定这是导致错误的实体/属性吗?如果是,您那里有任何列映射吗?
  • 贴出实际抛出的代码和full异常,包括调用栈。您可以使用Exception.ToString(). 轻松获得此信息,不要发布部分异常。完整的字符串包含任何内部异常、额外信息和完整的调用堆栈
  • 也许你应该寻找this post,它有类似的2位小数问题。它使用HasPrecision方法设置小数精度。

标签: c# sql-server asp.net-mvc entity-framework decimal


【解决方案1】:

检查 db 中的价格数据类型,可能你在 db 中使用了不同的数据类型

【讨论】:

  • 我的问题的第一行讲述了 db 列的数据类型
  • @IrfanYusanif - 始终值得仔细检查表格是否完全按照您的想法创建,而不是依赖查看您现在拥有的代码。
  • @PaulF 你说得对,我创建了新数据库以确保 db 列正是我所期望的,并且我也发布了有问题的表格屏幕截图。
  • @IrfanYusanif:这表明表格是正确的并且应该能够正确存储该值。您如何将 Price 设置为“12345678.00” - 数据绑定到代码中的控件或赋值 - 看到该代码可能会有所帮助。
  • @PaulF,我已经更新了问题,请看一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多