2012-02-11 3 views
11

Sono piuttosto nuovo in MVC e ho problemi con l'eliminazione a cascata. Per il mio modello ho i seguenti 2 classi:MVC .Net Eliminazione in cascata quando si utilizza il primo approccio al codice EF

public class Blog 
    { 
     [Key] 
     public int Id { get; set; } 
     [Required] 
     public string Name { get; set; } 
     [DisplayFormat()] 
     public virtual ICollection<BlogEntry> BlogEntries { get; set; } 
     public DateTime CreationDateTime { get; set; } 
     public string UserName { get; set; } 
    } 

    public class BlogEntry 
    { 
     [Key] 
     public int Id { get; set; } 
     [Required] 
     public string Title { get; set; } 
     [Required] 
     public string Summary { get; set; } 
     [Required] 
     public string Body { get; set; } 
     public List<Comment> Comments { get; set; } 
     public List<Tag> Tags { get; set; } 
     public DateTime CreationDateTime { get; set; } 
     public DateTime UpdateDateTime { get; set; } 
     public virtual Blog ParentBlog { get; set; } 

    } 

E per il mio controller ho impostato che seguendo il messaggio Elimina Indietro:

[HttpPost, ActionName("Delete")] 
public ActionResult DeleteConfirmed(int id) 
{ 
    Blag blog = db.Blogs.Find(id); 

    foreach (var blogentry in blog.BlogEntries) 
    { 
     //blogentry = db.BlogEntries.Find(id); 
     db.BlogEntries.Remove(blogentry); 
    } 
    db.Blogs.Remove(blog); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

problema è che non funzionerà non importa quale; I read this post ma mi sembra che funzioni solo per i modelli in cui la relazione è uno a uno, quindi sono perso qui, ho ricerca ovunque e non riesco a trovare la soluzione per questo problema, se qualcuno potrebbe indicare cosa mi manca sarebbe davvero bello :), grazie in anticipo, e ancora una volta, perdonate la mia nooobness ho appena iniziato, ma volevo affrontare un grande progetto per essere in grado di imparare molto.

risposta

15

Questo è dovuto al fatto EF di default non impone le eliminazioni a cascata per le relazioni opzionali. La relazione nel modello è desunta come facoltativa.

È possibile aggiungere una proprietà non annullabile scalare (BlogId) del FK

public class BlogEntry 
{ 
    [Key] 
    public int Id { get; set; } 
    [Required] 
    public string Title { get; set; } 
    [Required] 
    public string Summary { get; set; } 
    [Required] 
    public string Body { get; set; } 
    public List<Comment> Comments { get; set; } 
    public List<Tag> Tags { get; set; } 
    public DateTime CreationDateTime { get; set; } 
    public DateTime UpdateDateTime { get; set; } 

    public int ParentBlogId { get; set; } 

    public virtual Blog ParentBlog { get; set; } 
} 

O configurare questo utilizzando API fluente

modelBuilder.Entity<BlogEntry>() 
      .HasRequired(b => b.ParentBlog) 
      .WithMany(b => b.BlogEntries) 
      .WillCascadeOnDelete(true); 
+0

Yay! : D, grazie ha funzionato !, grazie mille, non ero a conoscenza dell'API fluente, ma mi sembra un buon modo per fare queste cose, tra l'altro, posso ottenere questo comportamento con le annotazioni dei dati ?. –

+0

@Q_ro Le annotazioni dei dati hanno un numero limitato di funzioni. – Eranga

1

non è sicuro che cosa il vostro cercando di fare qui, ma è necessario un record quindi non so perché il tuo tentativo di ciclo qui è il mio codice di eliminazione:

public ActionResult Delete(int id) 
    { 
     try { 
     Products products = context.Products.Single(x => x.productId == id); 
     return View(products); 
     } 
     catch (Exception ex) 
      { 
      ModelState.AddModelError("",ex.Message); 
      CompileAndSendError(ex); 
      return View(new Products()); 
      } 
    } 

    // 
    // POST: /Products/Delete/5 

    [HttpPost, ActionName("Delete")] 
    public ActionResult DeleteConfirmed(int id) 
    { 
     try { 
     Products products = context.Products.Single(x => x.productId == id); 
     context.Products.Remove(products); 
     context.SaveChanges(); 
     return RedirectToAction("Index"); 
     } 
     catch (Exception ex) 
      { 
      ModelState.AddModelError("",ex.Message); 
      CompileAndSendError(ex); 
      return RedirectToAction("Index"); 
      } 
    } 
+0

Beh, pensare in questo modo, ciascun prodotto, hanno una categoria, voglio eliminare anche quelle categorie quando elimini un prodotto, perché, come ora, se elimini un prodotto, le mie categorie saranno ancora presenti nel database. –

+0

sì ma il tuo codice dovrebbe mostrare solo il codice che contiene le categorie, dovresti anche avere una colonna abilitata/disabilitata per categorie ed elementi, in sostanza non dovresti rimuovere nulla, ma solo contrassegnare come eliminato questo riduce i problemi più tardi quando viene fatto riferimento a un ID ma non esiste più. se vuoi ottenere l'ID della categoria dall'oggetto, elimina la categoria e poi elimina l'oggetto originale ma dovresti scrivere codice per gestirlo meglio invece di rimuovere tutto :-) – davethecoder

+0

grazie per il consiglio, io lo terrò a mente :) –