Entity Frameworkでキーを手動で入力する

asp.net c# entity-framework entity-framework-core sql

質問

私は最初に単純なデータベースプロジェクトのためにEntity Frameworkのコードを使用しようとしています、そして私は私が単に理解することができない問題に出くわします。

EFがテーブルのIDを毎回自動的に1ずつ増やすように設定していることに気付きました。そのフィールドに手動で入力した値は完全に無視されます。いくつか検索した後、この動作を無効にする正しい方法は次のようになっていることが私の理解です。

modelBuilder.Entity<Event>().Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

しかし今、私はこのエラーを受けているだけなので、その理由はわかりません。

未処理の例外:System.Data.Entity.Infrastructure.DbUpdateException:エントリの更新中にエラーが発生しました。詳細は内部の例外を見てください。 ---

System.Data.UpdateException:エントリの更新中にエラーが発生しました。詳細は内部の例外を見てください。 ---> System.Data.SqlClient.SqlException:IDENTITY_INSERTがOFFに設定されている場合、テーブル 'Events'のidentity列に明示的な値を挿入できません。

もしそれが役に立つなら、ここに問題のPOCOクラスがあります。

public class Event
{
    [Key, Required]
    public int EventID { get; set; }

    public string EventType { get; set; } //TODO: Event Type Table later on
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public virtual ICollection<Match> Matches { get; set; }
    public virtual ICollection<EventParticipation> EventParticipation { get; set; }
}

前もって感謝します。

受け入れられた回答

デフォルトでは、Entity Frameworkは整数の主キーがデータベース生成(属性HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)追加またはProperty(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);呼び出しProperty(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);ます。

テーブルを作成する移行を見ると、これがわかります。

   CreateTable(
                "dbo.Events",
                c => new
                    {
                        EventID = c.Int(nullable: false, identity: true),
                        //etc
                    })
                .PrimaryKey(t => t.EventID );

次に、Fluent APIを使用してモデルをDatabaseGenerated.None変更しました。 EFはこれを移行に取り入れます。

AlterColumn("dbo.Events", "EventID", c => c.Int(nullable: false, identity: false))

そして生成されるSQLはこれです:

ALTER TABLE [dbo].[Events] ALTER COLUMN [EventID] [int] NOT NULL

これは実際にはかなりうずくまっていません。列からIDENTITYを削除するのは簡単なことではありません。テーブルを削除して再作成するか、新しい列を作成する必要があります。その後、データをコピーして外部キーを修正する必要があります。だからEFがあなたのためにそれをしていないのは驚くことではない。

あなたは自分自身のためにそれをする最善の方法を考え出す必要があります。 DatabaseGeneratedOption.Noneを指定したので、マイグレーションを0にロールバックして最初から再スキャフォールドすることも、手動でマイグレーションを変更してテーブルをドロップして再作成することもできます。

あるいは、列を削除して再作成することもできます。

DropColumn("Customer", "CustomerId"); 
AddColumn("Customer", "CustomerId", c => c.Long(nullable: false, identity: false));

編集またはカスタム移行操作でIDのオン/オフを切り替えることもできます


人気のある回答

私は属性を好むので、ここでは完全を期すための代替案を挙げます。

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

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

注:これはEF Coreでも機能します。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ