2012-12-12 9 views
10

私はエンティティのプライマリキー名を変更し、update-database -forceを実行できるシナリオを持っています。私が試したときにコードとエラーが出るのを見てください。EFコードの主キーの名前を最初に変更する方法は?

エンティティは:私はUpdate-database -Forceを実行すると、私は次のエラーを取得する

public class Team 
{ 
    [Key] 
    [HiddenInput(DisplayValue = false)] 
    public virtual int TeamId { get; set; } 

    [Display(Name = "Full Name:")] 
    public virtual string Name { get; set; } 
} 

public class Team 
{ 
    [Key] 
    [HiddenInput(DisplayValue = false)] 
    public virtual int Id { get; set; } 

    [Display(Name = "Full Name:")] 
    public virtual string Name { get; set; } 
} 

エンティティに変更しました。

Multiple identity columns specified for table 'Teams'. Only one identity column per table is allowed.

その命名規則の問題と私はそれが子エンティティクラスと後者、単にIDの競合参照するときTeamIdになるこの必要があります。

どのように私はこれを正常に行うことができますか?

+2

[Column( "Id")]属性を使用してTeamIdをプライマリキーIdにマッピングするか、列名とPOCO変数の両方にTeamIdという名前を付ける必要がありますか? –

+0

@ marvc1私はあなたの提案をしようとしています。私はすぐにお知らせします – Komengem

+0

@ marvc1ちょっとお友達、あなたの提案は働いているようです。 – Komengem

答えて

4

使用しているEFのバージョンによって異なります。 移行しても表示される結果は、

"drop column Id"と "add column TeamId"のようなものです。

あなたはすべての値および「子の接続」を失うことになる。これにより

......

私はこの時点で見ています唯一の「安全な」ソリューションは、移行と「手のSQL操作」のミックスです。

EASYソリューション:

の1-考慮して服用しますが、すでにIDを持つテーブルを作成する「ベース」移行を持って、今、「更新」で新しい移行を作成します。今はまだ実行しないでください。

2 - ファイルと生成された行の前に新しい行を作成し、SQLコマンドを使用することを開き、このような何か:

 SQL("ALTER TABLE table_name RENAME COLUMN old_name to new_name;"); 

これは、移行が列を削除する前に名前を変更し、新しいを作成します。 1つは、何が起こるのでしょう:あなたは削除の前に名前を変更すると、削除が実行されますが、それは "失敗"しますが、何も傷つけることはありません。

しかし、今質問する:なぜ私はこれを行うのですか?列を削除して列を削除して新しい行を作成しても、移行を使用している場合は、次回新しい移行ファイルが自動的に作成されます。

UPDATED解答#1

私はEntity Frameworkの移行について話すとき、私はこれを参照しています:あなたはパッケージマネージャコンソール、新しいファイル(の「アドオンの移行AddBlogUrl」コマンドを実行すると http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx * .cs)が作成されます。SQLを使用してこのファイル移行ファイルの

コマンドの例:

public partial class AddAbsencesTypesAndCategories : DbMigration 
    { 
     public override void Up() 
     { 
      CreateTable(
       "pvw_AbsenceType", 
       c => new 
        { 
         Id = c.Int(nullable: false, identity: true), 
         Name = c.String(nullable: false), 
         CountAsVacation = c.Boolean(nullable: false), 
         IsIncremental = c.Boolean(nullable: false), 
        }) 
       .PrimaryKey(t => t.Id); 

      ..... 

      AddColumn("pvw_Absence", "CategoryId", c => c.Int(nullable: false)); 
         AddForeignKey("pvw_Absence", "StatusId", "pvw_AbsenceStatusType", "Id"); 
      AddForeignKey("pvw_Absence", "CategoryId", "pvw_AbsenceType", "Id"); 
      CreateIndex("pvw_Absence", "StatusId"); 
      CreateIndex("pvw_Absence", "CategoryId"); 
      DropColumn("pvw_Absence", "MainCategoryId"); 
      DropColumn("pvw_Absence", "SubCategoryId"); 
      ...... 
      Sql(@" 
             SET IDENTITY_INSERT [dbo].[pvw_AbsenceStatusType] ON 
        INSERT pvw_AbsenceStatusType (Id, Name) VALUES (1, N'Entwurf')      
             SET IDENTITY_INSERT [dbo].[pvw_AbsenceStatusType] OFF 
      ");  
      ..... 
     } 

     public override void Down() 
     { 
      ........ 
     } 
+0

このアイデアは、文章2で、そのファイルを開くと言ったら、あなたはどんなファイルを参照していますか? Nomarlly私はSQL Server Management StudioでSQL文を実行しますが、目的のデータベースが見つからないようです。 – Komengem

+0

Entity Frameworkの移行に関する話は、これを参照しています:http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough aspxパッケージマネージャコンソールで「Add-Migration AddBlogUrl」コマンドを実行すると、新しいファイル(* .cs)が作成されます。 – Dryadwoods

+0

私はそれを自分で作成しない限り、私は見つけることができないので、EF5はこのファイルを作成します。 EF5は、MigrationフォルダにConfiguration.csを作成します。このファイルには、pconstructorとシードメソッドを持つ内部密封クラスがあります。 – Komengem

2

最も簡単な解決策は、データベースの主キーの名前を変更し、代わりにあなたの主キーにクラスをマッピングし、それには任意の名前を付けるしないことです。このように:

public class Team 
{ 
    [Key] 
    [HiddenInput(DisplayValue = false)] 
    [Column("Id")] //this attribute maps TeamId to the column Id in the database 
    public virtual int TeamId { get; set; } 

    [Display(Name = "Full Name:")] 
    public virtual string Name { get; set; } 
} 

個人的には、クラス名をIdとします。命名規則[TableName + Id]は、古いスクールであり、プライマリキー(外部キーの場合はそれに適しています)には過剰です。私にとっては、あなたのコード行にノイズを加えるだけです。 team.TeamIdteam.Idよりも優れていません。

+0

これは、データベースの名前を気にしない場合にのみ良い解決策です。 – Dryadwoods

+0

@emanyalpsidこれは私が今心配していることですが、コードは正常に実行されましたが、データベースの名前は前と同じままです。私は今、データベースを削除し、コードを最初に移行できるようにして、もう一度再作成することを検討しています。 – Komengem

+0

データベース内のデータを心配していない場合は、それをドロップして再作成してください。 –

2

marvc1とemanyalpsidの両方による提案をしっかりと実行した後。データベースを削除してもう一度作成することにしました。これは、単にVS2012のサーバーエクスプローラーでデータベースを削除するだけでなく、App_Dataの.mdfファイルも削除されていることを確認することで行います。 .mdfファイルは通常は非表示になっています。ソリューションエクスプローラのツールバーの下に表示されるので、[すべてのファイルを表示]をクリックすると表示されます。これらのステップが完了したときに、単にパッケージマネージャコンソールに以下のコードを実行します。

update-database -Verbose 

-Verboseは、単にあなたが作成しているものを確認することができます。それはあなたがデータベース名についてあまり心配していない場合、それはそれについて移動するための最も安全な方法で、データベース内の名前を変更しない以外

marvc1の回答

は、うまく動作します。

関連する問題