用于自动增加非标识列/并发问题的实体框架

时间:2013-07-12 19:44:41

标签: asp.net-mvc-4 entity-framework-5 database-concurrency

我有两张桌子:

CREATE TABLE [dbo].[Customers] (
    [CustomerId]  INT            IDENTITY (1, 1) NOT NULL,
    CONSTRAINT [PK_dbo.Customers] PRIMARY KEY CLUSTERED ([CustomerId] ASC)
);

CREATE TABLE [dbo].[Campaigns] (
    [Id]           INT            IDENTITY (1, 1) NOT NULL,
    [CustomerId]   INT            NULL,
    [CampaignId]   INT            NULL,
    CONSTRAINT [PK_dbo.Campaigns] PRIMARY KEY CLUSTERED ([Id] ASC)
);

Campaigns.CampaignId对每个CustomerId都是唯一的;因此,它不能是一种身份。因此,从我的网络应用程序,我需要在广告系列创建时自动增加CampaignId。在过去,我必须在单个事务中获得锁定以获得下一个最高点并发出插入。如何在不必担心或有效管理并发的情况下在EF中完成同样的事情?

在Campaign控制器中,我有这个(UserContext是一个静态帮助器类,它检索用户当前的CustomerId,db是我的DbContext):

public ActionResult Create(Campaign campaign)
{
    if (ModelState.IsValid)
    {
        int customerId = UserContext.customerId;
        int maxCampaignId = db.Campaigns.Where(c => c.CustomerId == customerId).Max(c => c.CampaignId);
        campaign.CampaignId = maxCampaignId + 1;
        db.Campaigns.Add(campaign);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(campaign);
}

但是,在高并发环境中,每个CustomerId会不会冒这个重复值?

编辑:

我忘了提一个guid不是一个选择。 Ids必须是整数。

编辑2:

我忘了提到还有一个Users表可以拥有相同的CustomerId。用户可以使用相同的CustomerId创建多个Campaign,这可能会导致并发问题。

1 个答案:

答案 0 :(得分:0)

您可能想要查看HiLo模式,或者只使用Guid.NewGuid()而不是递增。

请参阅:HiLO for the Entity Framework

What's the Hi/Lo algorithm?