SQL Server の値の生成

このページでは、SQL Server プロバイダーに固有の値生成の構成とパターンについて説明します。 まず、値の生成に関する概要ページを読むことをお勧めします。

IDENTITY 列

規則により、add で値が生成されるように構成された数値列は、SQL Server IDENTITY 列として設定されます。

シードとインクリメント

既定では、IDENTITY 列は 1 (シード) から開始され、行が追加されるごとに 1 ずつ増分されます (インクリメント)。 次のように、別のシードとインクリメントを構成できます。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.BlogId)
        .UseIdentityColumn(seed: 10, increment: 10);
}

IDENTITY 列への明示的な値の挿入

既定では、SQL Server では IDENTITY 列に明示的な値を挿入することはできません。 これを行うには、次のように、SaveChanges() を呼び出す前に手動で IDENTITY_INSERT を有効にする必要があります。

using (var context = new ExplicitIdentityValuesContext())
{
    context.Blogs.Add(new Blog { BlogId = 100, Url = "http://blog1.somesite.com" });
    context.Blogs.Add(new Blog { BlogId = 101, Url = "http://blog2.somesite.com" });

    context.Database.OpenConnection();
    try
    {
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs ON");
        context.SaveChanges();
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs OFF");
    }
    finally
    {
        context.Database.CloseConnection();
    }
}

Note

SQL Server プロバイダー内で自動的にこれを行うための機能要求が、バックログに用意されています。

シーケンス

IDENTITY 列の代わりに、標準のシーケンスを使用することもできます。 これはさまざまなシナリオで役立つことがあります。たとえば、複数の列が 1 つのシーケンスから既定値を取り出す必要があるような場合です。

シーケンスの概要ページで詳しく説明されているように、SQL Server ではシーケンスを作成して使用できます。 HasDefaultValueSql() を介してシーケンスを使用するには、お客様がプロパティを構成する必要があります。

GUID

GUID 主キーの場合、プロバイダーは、SQL Server の NEWSEQUENTIALID 関数と同様に、最適なシーケンシャル値を自動的に生成します。 クライアントでの値の生成は、一部のシナリオでより効率的です。つまり、キーを参照する依存オブジェクトも挿入される場合、データベースで生成される値を取得するための追加のラウンド トリップは必要ありません。

EF で非キーのプロパティに対して同じシーケンシャル GUID 値を生成するには、次のように構成します。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().Property(b => b.Guid).HasValueGenerator(typeof(SequentialGuidValueGenerator));
}

RowVersion

SQL Server には rowversion データ型があり、行が更新されるたびに自動的に変更されます。 これは、同じ行が複数のトランザクションによって同時に更新されるケースを管理するための、コンカレンシー トークンとしてとても役立ちます。

コンカレンシー トークンとその使用方法を完全に理解するには、コンカレンシーの競合に関する専用ページを参照してください。 byte[] プロパティを rowversion 列にマップするには、次のように構成します。

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [Timestamp]
    public byte[] Version { get; set; }
}