2015-10-19 7 views
6

Sto utilizzando Entity Framework 6 e il database SQLite (System.Data.SQLite.EF6), ma non riesco a creare una voce con la stessa chiave primaria immediatamente dopo averlo cancellato. Per esempio:Entity Framework 6 e SQLite: impossibile creare la voce con PK della voce cancellata prima di

Il mio modello di entità:

public class Person 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int Id { get; set; } 

    public int Name { get; set; } 
} 

PASSI:

1) inserisco l'istanza di questa entità person1 (con Id = 1) nella mia tabella di persone.

using (var context = new MyDbContext()) 
{ 
    context.Create(person1); 
    await context.SaveChangesAsync(); 
} 

2) Afters alcune tome a cancellare l'intera tabella persone con:

using (var context = new MyDbContext()) 
{ 
    await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`")); 
    await context.SaveChangesAsync(); 
} 

3) Io cerco di aggiungere la voce con stessa chiave primaria come l'ingresso dal 1 ° passo: Person2 (con id = 1)

using (var context = new MyDbContext()) 
{ 
    context.Create(person2); 
    await context.SaveChangesAsync(); 
} 

Ma nel 3 ° gradino, SaveChangesAsync() fallisce con

System.InvalidOperationException: le modifiche al database sono state eseguite correttamente, ma si è verificato un errore durante l'aggiornamento del contesto dell'oggetto. ObjectContext potrebbe trovarsi in uno stato incoerente. Messaggio eccezione interna: il salvataggio o l'accettazione delle modifiche non è riuscito perché più di un'entità di tipo "DbModels.PersonModel" hanno lo stesso valore di chiave primaria.

Quando aggiungo qualche altra voce dopo aver cancellato la tabella (con una chiave primaria diversa) e poi aggiunto la voce dal primo passaggio, funziona correttamente e entrambe le voci vengono salvate senza eccezioni.

Ho aggiunto un punto di interruzione direttamente prima della creazione di una nuova voce (dopo che la tabella è stata cancellata) e ho controllato la tabella Persone con lo strumento esterno e la tabella è vuota (quindi non vi è alcuna voce con id = 1).

UPDATE: DbContexte esteso + realizzazione del mio metodo Create:

public DbSet<PersonModel> Persons { get; set; } 

    public T Create<T>(T entity) 
     where T : class 
    { 
     try 
     { 
      GetDbSetForType<T>().Add(entity); 
      return entity; 
     } 
     catch (Exception ex) 
     { 
      return default(T); 
     } 
    } 

    private DbSet<T> GetDbSetForType<T>() 
     where T : class 
    { 
     var type = typeof(T); 

     if (type == typeof(PersonModel)) return Persons as DbSet<T>; 
     //...my other types 
     throw new Exception("Type not found in db"); 
    }  
+0

context.Create (person2) - è questo il tuo metodo? Perché non ricordo che EF ce l'abbia. Se è così, puoi mostrarlo? – Toddams

+0

@Toddams oh, mi dispiace, ho aggiunto il corpo del mio metodo Create alla domanda –

+0

Se elimini tutte le voci da PersonModels, potresti invece usare questo: 'attendi context.Database.ExecuteSqlCommandAsync (string.Format (" TRUNCATE TABLE 'PersonModels' "));" Funzionerebbe per te? – LocEngineer

risposta

0

contesti di database EF mantenere un elenco di oggetti che recuperato dal database in memoria fino a quando non viene distrutto o scaricato.

using (var ctx = new MyDbContext()) 
{ 
    var person1 = new Person { Id = 1 }; 
    ctx.Persons.Add(person1); 
    await ctx.SaveChangesAsync(); 

    await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`")); 

    // This is the secret 
    ((IObjectContextAdapter)ctx).ObjectContext.Detach(person1); 

    ctx.Persons.Add(person1) 
    await ctx.SaveChangesAsync(); 

} 
+0

Grazie, ma sto usando contesti separati (dopo aver cancellato la tabella Persone, dispongo il contesto e creo una nuova istanza di contesto per aggiungere una voce). Inoltre, my ((IObjectContextAdapter) ctx) .ObjectContext non contiene "Persons" (ho solo proprietà Persons nella mia implementazione di DbContext -> 'DbSet Persons', ma DbSet non ha Detach().) –

+0

I sicuramente non potrei riprodurre il problema nelle circostanze che hai descritto. Ho anche aggiornato l'esempio di codice 'Detach'. –

Problemi correlati