48

In seguito alla sezione "Code First Modeling" di Pluralsight "Getting Started with Entity Framework 5" course by Julie Lerman, ho creato due classi POCO con uno o uno zero -una relazione: un genitore (Utente) e un facoltativo figlio (UserDetail).Codice Entity Framework (EF) First Cascade Delete per la relazione One-to-Zero-one

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

Avviso nel diagramma che la proprietà UserId è una chiave primaria e una chiave esterna per UserDetail.

codice rilevante:

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(); 

     //... 
    } 
} 

Quando il metodo Delete() nella classe UserRepository si chiama, non eliminare il record utente nel database perché la chiave straniera in UserDetail non ha eliminazione a catena attivata.

L'istruzione DELETE è in conflitto con il vincolo di RIFERIMENTO "FK_dbo.UserDetail_dbo.User_UserId".

Come ti permetterà eliminazioni a catena per uno-a-zero-o-uno utilizzando Entity Framework primo codice (in modo che l'eliminazione di un utente elimina automaticamente UserDetail)?

risposta

65

Per eseguire questa operazione è necessario utilizzare l'API fluente.

Prova ad aggiungere quanto segue al DbContext:

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

Il WillCascadeOnDelete() è quello che ha fatto , anche se ho dovuto applicarlo sulla tabella dipendente (UserDetail), non il principale (utente) in questa relazione. Inoltre, ho rimosso le annotazioni dei dati Key e ForeignKey sulla proprietà UserId nella classe UserDetail. Grazie mille! – arsenalogy

+5

FWIW, questo articolo mi ha aiutato a ottenere l'idea di applicare WillCascadeOnDelete() alla tabella dipendente http://msdn.microsoft.com/en-us/data/jj591620.aspx#RequiredToOptional. – arsenalogy

+5

Esattamente quello di cui avevo bisogno. Alcuni hanno suggerito [Required] per eliminare a cascata. Questo funziona davvero, ma ovviamente, solo se è effettivamente richiesto. – CodeMonkey

0

Questo codice ha funzionato per me

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

Il codice di migrazione è stato:

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

e ha funzionato bene. Quando ho usato

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

Il codice di migrazione è stato:

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

ma non corrisponde a nessuno dei due sovraccarichi disponibili (in EntityFramework 6)