48

Pluralsight "Getting Started with Entity Framework 5" course by Julie Lermanの「コードファーストモデリング」セクションに続いて、に1対0または2のPOCOクラスを作成しました。 -one relationship:親(ユーザ)および(オプション)子(UserDetail)。エンティティフレームワーク(EF)コード最初のカスケード削除と1対0の関係

User and UserDetail data model diagram (click to view).

ユーザーIDプロパティは、主キーとUserDetailの外部キーである図でお知らせ。

関連するコード:

public class User 
{ 
    //... 

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

    /* Has a 1:0..1 relationship with UserDetail */ 
    public virtual UserDetail UserDetail { get; set; } 

    //... 
} 

public class UserDetail 
{ 
    //... 

    /* Has a 0..1:1 relationship with User */ 
    public virtual User User { get; set; } 

    [Key, ForeignKey("User")] 
    public int UserId { get; set; } 

    //... 
} 

public class EFDbContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    //public DbSet<UserDetail> UserDetails { get; set; } /* Explicit declaration not necessary. Context is aware of UserDetail entity due to 0..1:1 relationship with User */ 

    public EFDbContext() 
    { 
     Configuration.ProxyCreationEnabled = true; 
     Configuration.LazyLoadingEnabled = true; 
    } 
} 

public class UserRepository : IUserRepository 
{ 
    private EFDbContext _context = new EFDbContext(); 

    public void Delete(User entity) 
    { 
     entity = _context.Users.Find(entity.UserId); 

     //... 

     _context.Users.Remove(entity); 
     _context.SaveChanges(); 

     //... 
    } 
} 

UserRepositoryクラスのdelete()メソッドが呼び出されるとUserDetailの外部キーは、カスケードが有効になって削除に持っていないので、それはデータベース内のユーザーレコードを削除しません。

DELETE文がREFERENCE制約 "FK_dbo.UserDetail_dbo.User_UserId"と競合しました。あなたは(ユーザーを削除すると、自動的にUserDetailを削除するように)カスケードは、Entity Frameworkのコードファーストを使用して一から一ゼロツーか - 関係のために削除できるようになる方法

答えて

65

これを行うには、Fluent APIを使用する必要があります。追加あなたのDbContextに次の

試してみてください。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>() 
     .HasOptional(a => a.UserDetail) 
     .WithOptionalDependent() 
     .WillCascadeOnDelete(true); 
} 
+0

WillCascadeOnDelete()それをやったことあります(UserDetail)ではなく、この関係のプリンシパル(User)に適用する必要がありました。また、UserDetailクラスのUserIdプロパティでKeyおよびForeignKeyデータアノテーションを削除しました。どうもありがとうございます! – arsenalogy

+5

FWIW、この記事では、WillCascadeOnDelete()を従属テーブルhttp://msdn.microsoft.com/en-us/data/jj591620.aspx#RequiredToOptionalに適用する方法を知る手助けをしました。 – arsenalogy

+5

正確に私が必要としたもの。カスケード削除には[必須]と提案しているものがあります。これは実際には機能しますが、実際に必要な場合にのみ当然です。 – CodeMonkey

0

このコードは私

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<UserDetail>() 
      .HasRequired(d => d.User) 
      .WithOptional(u => u.UserDetail) 
      .WillCascadeOnDelete(true); 
    } 

移行コードに勤務されました:

public override void Up() 
    { 
     AddForeignKey("UserDetail", "UserId", "User", "UserId", cascadeDelete: true); 
    } 

そしてそれはうまく働きました。私が最初に

modelBuilder.Entity<User>() 
    .HasOptional(a => a.UserDetail) 
    .WithOptionalDependent() 
    .WillCascadeOnDelete(true); 

を使用する場合、移行コードはでした:

AddForeignKey("User", "UserDetail_UserId", "UserDetail", "UserId", cascadeDelete: true); 

が、それは(EntityFramework 6で)利用できる2つのオーバーロードのいずれとも一致しない

関連する問題