我有一个汇总根(Slave
),引用了anothe AG(Master
),也就是说,我在数据库中有一个外键约束。
这种可能性很小,但仍然有可能在插入引用Master
之前就删除引用的Slave
。可以避免使用repeatable read
或serializable
事务隔离级别,但这会对性能产生负面影响。
在这种情况下,我更喜欢乐观并发检查:尝试并可能失败。但是,很难将引发的DbUpdateEception
追溯到问题的语义。
换句话说,文本消息对于理解引用失败的人不是很方便:
更新条目时发生错误。看到内部异常 有关详细信息。
内部异常SqlException-“ INSERT语句与 FOREIGN KEY约束“ FK_Slaves_Masters_MasterId”。冲突 发生在数据库“ EFExperiments”的表“ dbo.Masters”的列中 'ID'。该语句已终止。”
我已经扫描了SqlEception
,看起来既没有索引名,也没有看起来单独存在列名的表,只是消息。但是,将此错误解释为包含实体名称和类型的'ReferencedEntityNotFoundException`会很好。这样就可以向用户显示友好消息,说明发生了什么:
Master(id = 123)不再存在。将Slave分配给另一个。
这里最好的方法是什么?是否可以使SQL Server更详细并返回表和列的名称,还是我必须解析消息?为此,是否存在任何EF扩展库?
P.S。还有一个选项可以完全消除FK约束,并允许悬挂的从属设备存在,它们向用户显示为无效状态。但这绝对是一个矫kill过正。
答案 0 :(得分:3)
没有这样的库,但是在代码中该位置出现的错误号547可能足以继续。
此外,您可以在消息中搜索特定的FK名称。从错误消息中提取对象名称应该是可靠的,因为它们是源代码的一部分,并且与语言无关。
例如:
catch (SqlException ex)
{
foreach (SqlError e in ex.Errors)
{
if (e.Number == 547 && e.Message.Contains("FK_Slaves_Masters_MasterId") )
{
throw new ReferencedEntityNotFoundException("Master", "Slave", slave.MasterId);
}
}
throw;
}