1

私は2つのテーブルを持っています:

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 に固有です。したがって、ID にすることはできません。したがって、Web アプリから、キャンペーンの作成時に CampaignId を自動インクリメントする必要があります。以前は、1 つのトランザクションでロックを取得して、次に高いトランザクションを取得し、挿入を発行する必要がありました。並行性について心配したり効果的に管理したりすることなく、EF で同じことを達成するにはどうすればよいでしょうか。

キャンペーン コントローラーには、次のようなものがあります (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はオプションではなかったことを忘れていました。ID は整数でなければなりません。

編集2:

同じ CustomerId を持つことができる Users テーブルもあることに言及するのを忘れていました。ユーザーは同じ CustomerId を使用して複数のキャンペーンを作成できるため、同時実行の問題が発生する可能性があります。

4

1 に答える 1

0

HiLo パターンを調べるか、インクリメントする代わりに Guid.NewGuid() を使用することをお勧めします。

参照: Entity Framework の HiLO

ハイ/ロー アルゴリズムとは何ですか?

于 2013-07-12T19:59:07.823 に答える