asp.net-mvc – 如何识别抛出System.Data.SqlClient.SqlException的列? (将datetime2数据类型转换为日期时间数据类型)

我已经覆盖了我的ApplicationDbContext.SaveChanges()方法.这有助于我在黄色和白色错误应用程序错误屏幕上提供立即可见的错误消息.

但是当DateTime列存在验证错误时,似乎没有激活catch子句.

这是为什么?我如何识别无效列?

覆盖方法

public partial class ApplicationDbContext 
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();  //**error is thrown here**//
        }
        catch (DbEntityValidationException ex)
        {
            var sb = new StringBuilder();

            foreach (var failure in ex.EntityValidationErrors)
            {
                sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
                foreach (var error in failure.ValidationErrors)
                {
                    sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                    sb.AppendLine();
                }
            }

            throw new DbEntityValidationException(
                "Entity Validation Failed - errors follow:\n" +
                sb.ToString(), ex
                ); 
        }
    }
}

但是,DateTime列不会引发异常,似乎未激活catch块.

最佳答案 TL; DR

>如果使用Sql DATETIME列,请在持久化实体上添加.Net DateTime属性的验证,以确保在.SaveChanges()之前的值介于1753和9999之间
>否则,将Sql存储更改为DATE或DATETIME2,具体取决于您的精度要求.

详细地
假设Sql Server DateTime数据类型只能存储1753 – 9999范围内的日期,而.Net DateTime结构可以存储更大的动态范围,而higher precision,即并非所有.Net DateTimes都可以存储在Sql Server DATETIME中.

特别容易出现此错误的是EF实体上的.Net DateTime属性,该属性未明确分配,因为默认(DateTime)是0001/01/01.

因此,优先使用DATETIME2或DATE存储替换DATETIME列.

结果,在> Sql 2005 RDBMS,Entity Framework将default改为Sql DATETIME2数据类型,因为这将允许存储超出DATETIME提供的有限范围并且更接近.Net数据类型.

但是,如果你确实有一个带有DATETIME列的现有表和attempt to bind an ‘out of band’ DateTime value,那么令人讨厌的是,Sql Server实际上并没有列出错误的列名.如果您能够在执行语句时运行Sql Profiler(或粘贴到LinqPad),则可以获取实际的Sql.但可能的候选人是DateTime,但尚未设置为> 1753(例如,将其统一为默认的DateTime).

你没有捕获异常的原因是因为catch DbEntityValidationException与抛出的SqlException之间的不相交.

点赞