2012-07-25 16 views
10

Ho seguito entità codice del framework primo codice. Le tabelle vengono create e i dati vengono inseriti. Tuttavia ci sono record duplicati nella tabella del club.Entity Framework: record duplicati in molti-a-molti

mie operazioni sono: -

  1. Creare club con club di creazione di applicazioni

  2. Crea persone utilizzando persona app

Come evitare la voce duplicata?

enter image description here

static void Main(string[] args) 
    { 
     Database.SetInitializer<NerdDinners>(new MyInitializer()); 

     CreateClubs(); 
     InsertPersons(); 

    } 

    public static void CreateClubs() 
    { 

     string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
     using (var db = new NerdDinners(connectionstring)) 
     { 

      Club club1 = new Club(); 
      club1.ClubName = "club1"; 

      Club club2 = new Club(); 
      club2.ClubName = "club2"; 

      Club club3 = new Club(); 
      club3.ClubName = "club3"; 

      db.Clubs.Add(club1); 
      db.Clubs.Add(club2); 
      db.Clubs.Add(club3); 

      int recordsAffected = db.SaveChanges(); 


     } 
    } 

    public static Club GetClubs(string clubName) 
    { 
     string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
     using (var db = new NerdDinners(connectionstring)) 
     { 

      //var query = db.Clubs.Where(p => p.ClubName == clubName); 
      var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName); 
      return query; 
     } 
    } 

    public static void InsertPersons() 
    { 
     string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
     using (var db = new NerdDinners(connectionstring)) 
     { 

      Club club1 = GetClubs("club1"); 
      Club club2 = GetClubs("club2"); 
      Club club3 = GetClubs("club3"); 

      Person p1 = new Person(); 
      p1.PersonName = "Person1"; 

      Person p2 = new Person(); 
      p2.PersonName = "Person2"; 

      List<Club> clubsForPerson1 = new List<Club>(); 
      clubsForPerson1.Add(club1); 
      clubsForPerson1.Add(club3); 

      List<Club> clubsForPerson2 = new List<Club>(); 
      clubsForPerson2.Add(club2); 
      clubsForPerson2.Add(club3); 

      p1.Clubs = clubsForPerson1; 
      p2.Clubs = clubsForPerson2; 

      db.Persons.Add(p1); 
      db.Persons.Add(p2); 

      int recordsAffected = db.SaveChanges(); 


     } 
    } 

Domain

public class Person 
{ 
    public int PersonId { get; set; } 
    public string PersonName { get; set; } 
    public virtual ICollection<Club> Clubs { get; set; } 
} 

public class Club 
{ 
    public int ClubId { get; set; } 
    public string ClubName { get; set; } 
    public virtual ICollection<Person> Members { get; set; } 
} 

//System.Data.Entity.DbContext is from EntityFramework.dll 
public class NerdDinners : System.Data.Entity.DbContext 
{ 

    public NerdDinners(string connString): base(connString) 
    { 

    } 

    protected override void OnModelCreating(DbModelBuilder modelbuilder) 
    { 
     //Fluent API - Plural Removal 
     modelbuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 

    public DbSet<Person> Persons { get; set; } 
    public DbSet<Club> Clubs { get; set; } 

} 
+1

Hai eseguito due volte? – podiluska

+0

@podiluska. No, l'ho eseguito solo una volta. – Lijo

risposta

18

Il problema è che si crea più contesti.

Prima si crea il club. Va bene. Ma quando si creano le persone, è prendere il club tramite GetClubs, ma per ogni club di smaltire contesto quadro effettiva entità così si finisce con entità indipendenti. Al numero InsertPersons aggiungi entità di club distaccate alle nuove persone in modo che il contesto attuale possa pensare che i club siano nuovi club.

Quindi, quando si aggiunge un club ad una persona che effettivamente creare nuovi club.

Questo perché Entity Framework tiene traccia delle modifiche e gestisce le entità per contesto. Se aggiungi un'entità a un contesto che non lo contiene ancora, verrà trattato come una nuova entità.

In realtà, si dovrebbe fare qualcosa di simile (non testato):

static void Main(string[] args) 
{ 
    Database.SetInitializer<NerdDinners>(new MyInitializer()); 

    string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
    using (var db = new NerdDinners(connectionstring)) 
    { 
     CreateClubs(db); 
     InsertPersons(db); 
    } 

} 

public static void CreateClubs(NerdDinners db) 
{ 
    Club club1 = new Club(); 
    club1.ClubName = "club1"; 

    Club club2 = new Club(); 
    club2.ClubName = "club2"; 

    Club club3 = new Club(); 
    club3.ClubName = "club3"; 

    db.Clubs.Add(club1); 
    db.Clubs.Add(club2); 
    db.Clubs.Add(club3); 

    int recordsAffected = db.SaveChanges(); 
} 

public static Club GetClubs(string clubName, NerdDinners db) 
{ 
    //var query = db.Clubs.Where(p => p.ClubName == clubName); 
    var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName); 
    return query; 
} 

public static void InsertPersons(NerdDinners db) 
{ 
    Club club1 = GetClubs("club1", db); 
    Club club2 = GetClubs("club2", db); 
    Club club3 = GetClubs("club3", db); 

    Person p1 = new Person(); 
    p1.PersonName = "Person1"; 

    Person p2 = new Person(); 
    p2.PersonName = "Person2"; 

    List<Club> clubsForPerson1 = new List<Club>(); 
    clubsForPerson1.Add(club1); 
    clubsForPerson1.Add(club3); 

    List<Club> clubsForPerson2 = new List<Club>(); 
    clubsForPerson2.Add(club2); 
    clubsForPerson2.Add(club3); 

    p1.Clubs = clubsForPerson1; 
    p2.Clubs = clubsForPerson2; 

    db.Persons.Add(p1); 
    db.Persons.Add(p2); 

    int recordsAffected = db.SaveChanges(); 
} 

Naturalmente si dovrebbe refactoring la struttura di questo codice, ma si prega di notare che io uso un solo contesto EF per le mie operazioni.

+0

vedere le mie modifiche e il codice di esempio –

+0

In questo esempio di codice, c'è solo un contesto EF. Ho bisogno di contesti EF separati. qualche idea? – Lijo

+1

se si desidera utilizzare le entità di origini diverse rispetto al contesto effettivo, è necessario allegarle: http://msdn.microsoft.com/en-us/library/bb896271.aspx –

0

Grazie @PeterPorfy

visualizzato anche Exception of type 'System.ObjectDisposedException'

Ho usato

((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)entity); 

per fissare gli oggetti dal contesto precedente.

Un esempio per IEntityWithKey che ho usato è il seguente. Si prega di commentare se si vede qualche problema con questo approccio.

public class Person : IEntityWithKey 
{ 
    public int PersonId { get; set; } 
    public string PersonName { get; set; } 

    public EntityKey EntityKey { get; set; } 
} 

prega di fare riferimento alla seguente anche

  1. Problem with SaveChanges() Entity Framework 4.1
  2. Entity Framework Updating Many-To-Many Relationships - POCO

+0

Per coloro che non conoscono nulla - Sono interessato per vedere perché c'è un downvote. C'è qualcosa di sbagliato in questa risposta? – Lijo

+0

Immagino che preferiscano che la risposta di Peter sia contrassegnata come corretta. Sto solo dicendo – Miro

+0

Non ho downvoted. – Miro

Problemi correlati