如何处理有关聚合根之间的引用的并发性?

时间:2018-10-03 16:58:36

标签: sql-server domain-driven-design ef-core-2.1

我有一个汇总根(Slave),引用了anothe AG(Master),也就是说,我在数据库中有一个外键约束。

这种可能性很小,但仍然有可能在插入引用Master之前就删除引用的Slave。可以避免使用repeatable readserializable事务隔离级别,但这会对性能产生负面影响。

在这种情况下,我更喜欢乐观并发检查:尝试并可能失败。但是,很难将引发的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过正。

1 个答案:

答案 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;    
}