我已覆盖了我的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块。
答案 0 :(得分:2)
TL; DR
DATETIME
列,请在持久化实体上添加.Net DateTime属性验证,以确保1753
之前的值9999
和.SaveChanges()
之间的值DATE
DATETIME2
或1753 - 9999
,具体取决于您的精度要求。 详细信息
鉴于Sql Server DateTime
数据类型只能存储范围DATETIME
中的日期,而.Net DateTime结构可以存储更大的动态范围,而higher precision,即并非所有.Net DateTimes都可以存储在Sql Server DateTime
中。
特别容易出现此错误的是EF实体上的.Net default(DateTime)
属性,该属性未明确分配,因为DATETIME
为0001/01/01。
因此,首选将DATETIME2
列替换为DATE
或DATETIME2
存储空间。
结果,在> Sql 2005 RDBMS,Entity Framework将default转换为Sql DATETIME
数据类型,因为这将允许存储超出DATETIME
提供的有限范围,并且更接近.Net数据类型。
但是,如果您确实有一个带有Exception
列的现有表而且attempt to bind an 'out of band' DateTime value,那么令人讨厌的是,Sql Server实际上并没有列出错误的列名。如果您能够在执行语句时运行Sql Profiler(或粘贴到LinqPad),则可以获取实际的Sql。但是可能的候选者是没有被设置为>的DateTime。 1753(例如,将其统一为默认的DateTime)。
你没有抓住catch DbEntityValidationException
的原因是因为SqlException
与被抛出的{{1}}之间不相交。
答案 1 :(得分:0)
如果我没有弄错你在MSSQL中使用smalldatetime,在某些情况下可能会抛出此错误。 检查this帖子以获得答案。
尝试抓住catch(Exception ex)
,然后您就可以看到确切的错误消息。