54

最初に単純なデータベース プロジェクトに 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' の ID 列に明示的な値を挿入できません。

参考になれば、問題の 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; }
}

前もって感謝します。

4

2 に答える 2

91

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

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

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

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

于 2016-05-02T14:02:48.187 に答える
41

既定では、Entity Framework は、整数の主キーがデータベースで生成されたものであると想定します (属性の追加またはFluent API での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 がそれを行わないことは驚くべきことではありません。

自分にとって最善の方法を考える必要があります。を指定したので、移行を 0 にロールバックして最初から再スキャフォールディングするDatabaseGeneratedOption.Noneか、手動で移行を変更してテーブルを削除して再作成することができます。

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

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

編集または、カスタム移行操作でアイデンティティのオン/オフを切り替える ことができます

于 2013-09-20T12:55:03.300 に答える