You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用_tld.SaveChanges()时SqlException异常的解决方案咨询

问题描述

调用_tld.SaveChanges();时出现如下错误:

SqlException: 将datetime类型转换为datetime2数据类型时导致值超出范围。语句已终止。

项目采用Entity Framework数据库优先模式和SQL Server,求该问题的解决方案。

异常相关代码

public static Result SavePendingTransactionsData(transaction[] model)
{
    Authorize authorize = new Authorize();

    using (TechLogisticsEntities _tld = new TechLogisticsEntities())
    {
        try
        {
            foreach (var item in model)
            {
                L_ROD_AsTwentyFourTransaction asTwentyFourTransaction = new L_ROD_AsTwentyFourTransaction();
                asTwentyFourTransaction.TransactionNumber = item.transactionNumber;
                asTwentyFourTransaction.TransactionType = item.transactionType;
                asTwentyFourTransaction.TransactionDate = item.entryTransactionDate;
                asTwentyFourTransaction.VehiclePlate = item.VCRegistrationNumber;
                asTwentyFourTransaction.VehicleId = int.Parse(item.VCNumber);
                //asTwentyFourTransaction.TransactionAmount =
                //asTwentyFourTransaction.CurrencyId =
                //asTwentyFourTransaction.CurrencyCode =
                //asTwentyFourTransaction.GrossAmount =
                //asTwentyFourTransaction.TransactionValue =
                //asTwentyFourTransaction.Unit =
                //asTwentyFourTransaction.TransactionCountryName =
                //asTwentyFourTransaction.TransactionCountryCode =
                //asTwentyFourTransaction.TransactionLocation =
                //asTwentyFourTransaction.ObuId =
                //2 olan 
                asTwentyFourTransaction.StatusId = 1;
                //asTwentyFourTransaction.StatusCode =

                _tld.L_ROD_AsTwentyFourTransaction.Add(asTwentyFourTransaction);
                _tld.SaveChanges();
            }

            return new Result() { IsSuccess = true };
        }
        catch (Exception ex)
        {
            return new Result() { IsSuccess = false, UserMessage = ex.Message };
        }
    }
}
解决方案

这个错误的核心原因是:SQL Server的datetime类型范围为1753年1月1日 ~ 9999年12月31日,而.NET的DateTime默认值是0001年1月1日,当EF将该默认值转换为SQL的datetime2(范围更大)后插入datetime字段时,就会触发范围超出的报错。结合你的代码,可按以下方式解决:

1. 校验并修正TransactionDate的赋值

确认item.entryTransactionDate是否为有效日期,是否存在DateTime.MinValue(0001-01-01)或早于1753-01-01的情况。如果是,给它设置符合SQL datetime范围的默认值:

// 若entryTransactionDate无效,替换为当前时间或合法起始日期
asTwentyFourTransaction.TransactionDate = item.entryTransactionDate == DateTime.MinValue 
    ? DateTime.Now 
    : item.entryTransactionDate;

2. 处理未赋值的日期字段

代码中存在大量注释未赋值的字段,需检查这些字段对应的数据库列是否为datetime类型且不允许为NULL。如果是未赋值的非空datetime字段,EF会自动填充DateTime.MinValue,导致插入失败。解决方式二选一:

  • 在数据库中将这些字段设置为允许NULL;
  • 在实体类中给这些字段设置合法默认值(如DateTime.Now或1753-01-01之后的日期)。

3. 将数据库字段类型改为datetime2(推荐)

如果业务允许,直接把数据库中对应的datetime字段改为datetime2类型。datetime2的范围与.NET的DateTime完全匹配(0001年1月1日 ~ 9999年12月31日),从根源避免类型转换的范围问题。操作步骤:

  1. 打开SQL Server Management Studio,找到目标表和字段;
  2. 修改字段类型为datetime2(可保留原有精度,如datetime2(7));
  3. 在EF数据库优先模式下,重新从数据库生成实体模型。

4. 配置EF的日期转换规则

若不想修改数据库,可在EF模型配置中指定字段使用datetime类型,避免自动转换为datetime2。在实体配置类中添加:

modelBuilder.Entity<L_ROD_AsTwentyFourTransaction>()
    .Property(t => t.TransactionDate)
    .HasColumnType("datetime");

或者在EDMX模型文件中,找到对应属性,将其Type设置为datetime而非datetime2。

内容的提问来源于stack exchange,提问作者melike aslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:37:27