2013-05-10 26 views
5

私は外部キーと1対1の関係を持っていますが、何らかの理由でCascade Deleteが有効になっていません。サンプルコードは以下のとおりです。コードfirst one-to-one enableカスケード削除

public class AppRegistration 
{ 
    public int AppRegistrationId { get; set; } 
    [Required] 
    [StringLength(50)] 
    [Display(Name = "Username")] 
    public string UserName { get; set; } 
    [Required] 
    [StringLength(100)] 
    public string Password { get; set; } 
    [StringLength(20)] 
    public string StudentOrAgent { get; set; } 
    // navigation properties 
    public virtual AppStatus AppStatus { get; set; } 
    public virtual Agreement Agreement { get; set; } 
    public virtual AnotherTable AnotherTable { get; set; } 
} 

外部キーを持つ従属テーブルは以下のとおりです。

public class Agreement 
{ 
    [Key] 
    [ForeignKey("AppRegistration")] 
    public int AppRegistrationId { get; set; } 
    public DateTime DateAgreed { get; set; } 
    public virtual AppRegistration AppRegistration { get; set; } 
} 

生成されたAppRegistrationsテーブルからエントリを削除しようとすると、参照制約の競合が発生します。

私は従属テーブルにナビゲーションプロパティに[Required]を入れてみましたが、それは何もしません - Update-DatabaseコマンドはNo pending code-based migrations.メッセージが表示されます。何か案は?ありがとう。

アップデート:私は、次のエラーメッセージが出てい

The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.AppStatus_dbo.AppRegistrations_AppRegistrationId". The conflict occurred in database "MVCapp", table "dbo.AppStatus", column 'AppRegistrationId'.

答えて

8

私は別のサンプルプロジェクトでcascade delete問題を解決することにしました。私は次のブログ& MSDNのページが非常に便利であることがわかりました。以下のモデルを作成Code Firstのアプローチを使用して

public class Category 
{ 
    public int CategoryId { get; set; } 
    public string CategoryName { get; set; } 
    public virtual Book Book { get; set; } 
} 
public class Book 
{ 
    public int CategoryId { get; set; } 
    public string BookTitle { get; set; } 
    public string BookAuthor { get; set; } 
    public string BookISBN { get; set; } 
    public virtual Category Category { get; set; } 
} 

は(私は、エンティティ名は1対多の関係を示唆して実現するが、私は一番上に私の元の質問のように、1対1の関係をモデル化しようとしています。)

ので、上記のモデルでは、それぞれカテゴリは、書籍のいずれか1つしか持つことができません。

DbContext由来のクラスには、以下を追加してください。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

    modelBuilder.Entity<Book>() 
     .HasKey(t => t.CategoryId); 

    modelBuilder.Entity<Category>() 
     .HasRequired(t => t.Book) 
     .WithRequiredPrincipal(t => t.Category) 
     .WillCascadeOnDelete(true); 
} 

(次の名前空間は、上記のコードのために必要とされる:。System.Data.EntitySystem.Data.Entity.ModelConfiguration.Conventions

これは適切に1対1の関係を作成します。各テーブルにプライマリキーがあり、Bookテーブルの外部キーもON DELETE CASCADEが有効になります。私は、引数依存性テーブルの外部キー列であるt => t.Category引数とWithRequiredPrincipal()を使用Categoryエンティティに上記のコードで

Database Diagram for the model

、。

あなたはなしWithRequiredPrincipal()引数を使用している場合は、Bookテーブル内の余分な列を得るでしょうし、あなたがCategoryテーブルにCategoryIdBookテーブルポインティングにおける2つの外部キーを持っています。

この情報が役立ちますように。

その後、私はここで直接答えを見つけに

UPDATE:答えのため

http://msdn.microsoft.com/en-us/data/jj591620#RequiredToRequired

5

あなたの関係はオプションであるため、削除カスケード接続することで取得していない理由。

したい場合はAppRegistrationすなわち、必要な関係は(カスケード接続が自動的に構成されたDELETE)あなたが使用できる1 Agreementを持つことがあります。

public class Agreement 
{ 
    ... 
    [Required] 
    public AppRegistration AppRegistration{ get; set; } 
} 

あなたは関係が削除カスケードで、オプションになりたい場合は、これを設定することができますFluent APIを使用して:

modelBuilder.Entity<AppRegistration>() 
    .HasOptional(a => a.Agreement) 
    .WithOptionalDependent() 
    .WillCascadeOnDelete(true); 
+0

感謝。私は '[Required]'を入れてみましたが、コードマイグレーションの 'Update-Database'は' No pending code-based migrations'を返します。これを回避する方法はありますか? – erdinger

+1

私は間違っているかもしれませんが、両方向で必要とされる一対一の関係を満たすことはほとんど不可能であるため、最初の手法を試したくないと思います。契約を挿入しようとすると、AppRegistrationが存在しないために制約違反が発生し、その逆もあります。 – AaronLS

+0

@ user2291748 update-databaseを実行する前に移行を追加しましたか? AaronLS、おそらくあなたが正しいと思うかもしれません。 – MattSull

関連する問題