web-dev-qa-db-ja.com

EF Core 3.1を使用してSQL Serverシーケンスの「次の値」を取得する-不可能ですか?

新しいASP.NET Core Web APIを作成しています。私の要件の1つは、EF Core 3.1を利用して、SQL ServerでIDとして定義されているsequenceの次の値を取得できるようにすることです。保存する必要があるレコードについて。

私はこれを行う方法を見つけるのに苦労しています-EF 6.xでは、次のようにDbContextの子孫に対して直接メソッドを使用しました:

_public int GetNextSequenceValue()
{
    var rawQuery = Database.SqlQuery<int>("SELECT NEXT VALUE FOR dbo.TestSequence;");
    var task = rawQuery.SingleAsync();
    int nextVal = task.Result;

    return nextVal;
}
_

2.1までのEF Coreの場合、Database.ExecuteSqlCommand()を使用してSQLスニペットを実行し、結果を返すことができました。しかし、EF Core 3.xでは、私は運が悪いようです...

DbSetには.FromSqlRaw()メソッドと_.FromSqlInterpolated_メソッドがあることを知っていますが、必要なのはシーケンスの次の値(INT)だけなので、それは飛ばないでしょう。そして、これらのメソッドが_context.Database_レベルにも存在することも知っています。これは、EF 6.xにあったものに非常に近いように見えますが、ここでは、これらのメソッドはonlyを返します。影響を受ける行数-SEQUENCEから新しい値を送り返す方法が見つかりません。

EF Core 3.xでは、その値をフェッチするために、昔のADO.NETコードに実際に戻る必要があるのでしょうか? [〜#〜] really [〜#〜]任意のSQLスニペットを実行してコンテキストから結果を返す方法はありませんか?

3
marc_s

Fluent API設定で、IDをシーケンスの次の値に自動的に設定する移行を作成できます

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasSequence<int>("OrderNumbers");

    modelBuilder.Entity<Order>()
        .Property(o => o.OrderNo)
        .HasDefaultValueSql("NEXT VALUE FOR shared.OrderNumbers");
}

シーケンスを作成する場合:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasSequence<int>("OrderNumbers", schema: "shared")
        .StartsAt(1000)
        .IncrementsBy(5);
}

ここからさらに読む: https://www.talkingdotnet.com/use-sql-server-sequence-in-entity-framework-core-primary-key/

1
olk

醜いが、私が思いつくことができる最高のもの:

var connection = repcontext.Database.GetDbConnection();
connection.Open();
using var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT NEXT VALUE FOR AA.TransSeq;";
var obj = cmd.ExecuteScalar();
connection.Close();
seqnum = (int)obj;
0
Jim