当DatabaseGenerated.Identity已与Entity Framework一起使用时自动递增数字

时间:2014-08-18 23:17:07

标签: c# entity-framework identity optimistic-locking

我们有一种情况,我们使用Guids作为表键。从技术上讲,我们选择了GUID,因为它们的碰撞几率很低,而且这个应用程序有一天会被分发,并且每个位置之间会有一个夜间数据同步(因此需要低碰撞机会ID)

但是,企业需要一个人类可读的号码,可用于屏幕上,印刷的报告,标签,以及用于对话。为此,我们使用一个5位数字,从10000开始。这些数字可以跨位置复制(位置A将有一个请求10000,位置B也会有)。

我们的模型看起来像这样:

Public Class Request
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public int Number { get; set; }
}

然后在我们的保存方法中,我们目前正在做这样的事情:

newRequestNumber = (_dbContext.Requests.Max(r => r.RequestNumber)) + 1;

request.Number = newRequestNumber

_dbContext.Requests.Add(request);

_dbContext.SaveChanges()

显然这是非常天真的,我们现在遇到的问题是这个数字是重复的。

据我所知,我们无法使用DatabaseGeneratedOptions.Idnetity注释Number属性,因为它已被使用过一次。我也找不到任何可以使用Fluent API设置的内容,将此字段标记为自动生成的数字。

我最初的想法是转向某种乐观的锁定策略。我们将为请求编号添加一个唯一约束,然后尝试将其保存在try / catch中。如果没有保存,再次抓住数字,冲洗并重复。这样做的问题是,如果请求由于除了唯一数字约束之外的其他原因而无法保存,我们将陷入循环。

我觉得我在这里缺少一个相当明显的解决方案,任何想法?

1 个答案:

答案 0 :(得分:1)

您可以创建一个包含单个列的表来保存整数键,并创建另一个名称列。您可以根据需要增加,可以添加更多行来表示不同类型的代理键。

我不会使用标识,因为这需要您插入许多行...只需更新给定行的列。