web-dev-qa-db-ja.com

Entity Framework Coreを使用した部分的なプライマリキーの自動インクリメント

EF Core fluent APIを使用して次のモデルを宣言しました。

modelBuilder.Entity<Foo>()
    .HasKey(p => new { p.Name, p.Id });

PostgreSQLでデータベースを作成すると、両方のフィールドが主キーとしてマークされますが、Idフィールドは自動インクリメントとしてマークされません。私も追加しようとしました

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

fooの下のIdフィールドには、移行コードに違いはありません。 Id AIはPPKですが、作成する方法はありますか?

35
Martin

まあ、それらのデータアノテーションはトリックを行う必要があります。おそらく、PostgreSQLプロバイダーに関連するものです。

EF Coreドキュメント から:

使用されているデータベースプロバイダーに応じて、EFによってクライアント側またはデータベースで値が生成される場合があります。値がデータベースによって生成される場合、EFは、エンティティをコンテキストに追加するときに一時的な値を割り当てる場合があります。この一時的な値は、SaveChangesの間にデータベースで生成された値に置き換えられます。

また、このFluent Api構成を試すこともできます。

modelBuilder.Entity<Foo>()
            .Property(f => f.Id)
            .ValueGeneratedOnAdd();

しかし、先ほど言ったように、これはDBプロバイダーに関連するものだと思います。 DBに新しい行を追加して、Id列に値が生成されたかどうかを後で確認してください。

44
octavioccl

まず、Fluent Apiをデータアノテーションとマージしないようにしてください。以下のいずれかを使用することをお勧めします。

キーを正しく設定していることを確認してください

modelBuilder.Entity<Foo>()
            .HasKey(p => new { p.Name, p.Id });
modelBuilder.Entity<Foo>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

またはデータ注釈を使用して達成することもできます

public class Foo
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key, Column(Order = 0)]
    public int Id { get; set; }

    [Key, Column(Order = 1)]
    public string Name{ get; set; }
}
12

SQL Server Databaseを使用していて、int主キーに次の注釈を追加した後でも例外がスローされているこの質問に出会った人には

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

SQLを確認し、主キーの横に「IDENTITY(startValue、increment)」があることを確認してください。

CREATE TABLE [dbo].[User]
(
    [Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
)

これにより、新しい行が追加されるたびにデータベースがIDをインクリメントします。開始値は1、インクリメントは1です。

私の人生で1時間かかったSQLで誤って見落としていたので、これが誰かの助けになることを願っています!!!

8
Saif Asad

以下のようにプロパティに注釈を付けます

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }

新しいモデルのすべての値生成プロパティにID列を使用するには、コンテキストのOnModelCreating():に以下を配置するだけです

builder.ForNpgsqlUseIdentityColumns();

これにより、.ValueGeneratedOnAdd()を持つすべてのキーおよびその他のプロパティにデフォルトでIdentityが作成されます。 ForNpgsqlUseIdentityAlwaysColumns()を使用して常にIdentityを持つことができます。また、UseNpgsqlIdentityColumn()およびUseNpgsqlIdentityAlwaysColumn()を使用してプロパティごとにIDを指定することもできます。

postgres efcore値の生成

4

IDを生成するために、PostgreSQLのシリアルとして列タイプを指定します。

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order=1, TypeName="serial")]
public int ID { get; set; }

https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL

0
Naveen Verma