0

J'ai la table entry et une table type. Un entry a un type un type peut être dans plusieurs entrées (relation n-à-1). Le type est affiché dans un ComboBox modifiable. Si l'utilisateur entre un type qui n'existe pas encore, il doit être créé et le type du entry associé doit être mis à jour vers la nouvelle entité de type.Ajouter une nouvelle entité enfant et mettre à jour l'entité parent en un tour

Comment je charge les entrées (chargement avec impatience):

var entries = dbContext.entry.Include(entry => entry.type).ToList(); 

Comment je lie le type à la Combobox:

<Combobox IsEditable="True" 
    ItemsSource="{Binding AllTypes, Source={StaticResource typeTableController}}" 
    SelectedValue="{Binding Path="Entry.type"}" /> 

typeTableController possède une propriété (AllTypes) avec tous les types existants dans le DB. Entry est actuellement sélectionné entry. L'utilisateur peut maintenant modifier le texte ComboBox. S'il appuie sur un bouton "Enregistrer", ce type doit être ajouté à la base de données s'il n'existe pas encore ou s'il doit être sélectionné s'il existe. Et l'entrée mise à jour doit être enregistrée. Ce serait génial si je n'avais pas à gérer toutes les propriétés par moi-même parce que je ne suis pas le seul à avoir le type.

Mes premières approches:

dbContext.Set(entry.getType()).Attach(entry); 
dbContext.SaveChanges(); 

->InvalidOperationException: violation de contrainte d'intégrité référentielle

ou

dbContext.Entry(formEntry.type).State = EntityState.Added; 
dbContext.Set(entry.getType()).Add(entry); 
dbContext.SaveChanges(); 

-> Ajoute la nouvelle type à la table de type, mais également de dupliquer tous les types et les entrées dans le type/table d'entrée (ce qui est vraiment étrange pour moi) et met à jour seulement le type de l'un des deux entries maintenant à la nouvelle type. Donc, s'il y avait 10 types avant, il y a maintenant 21.

Edit: mon entrée:

public partial class entry 
{ 
    ... 
    public Nullable<int> type_id { get; set; } 
    ... 
    public virtual type type { get; set; } 
} 

Important: Je suis toujours plante lorsque je tente

dbContext.Entry(entry).State = EntityState.Modified; 

La raison était, que j'avais entry dans ma liste de surveillance de débogueur. Il semble que cela mène à des conflits. Le supprimer corrige ce problème.

Répondre

1

Déterminez si le type est existant ou ajouté par l'utilisateur. Vérifiez type.Id == 0 pour une nouvelle entité de type.

if (typeFromCombobox.Id == 0){ 
    //new type added 
    dbContext.Set<type>().Add(typeFromCombobox) 
} 
entity.type = typeFromCombobox // EF should handle this if you didn't call 'Detach' before 
dbContext.SaveChanges() 

Modifier: pas sûr: vous utilisez combobox liaison qui devrait changer automatiquement entity.type lorsque l'utilisateur sélectionner.Ainsi, la ligne entity.type = typeFromCombobox est rebundant

Edit 2: Je crée sample code

Il fonctionne très bien et les deux entity.typeid et entity.type.id ont été mis à jour après SaveChanges appel

Mais si je décommenter this.Configuration.AutoDetectChangesEnabled = false;entity.typeid ne sera pas mis à jour avant Je téléphone context.ChangeTracker.DetectChanges(); manuellement

Édition 3: Si vous avez modifié dbContext entre charger et enregistrer, vous devez attacher votre entité au nouveau contexte

dbContext.Set<entity>().Attach(entity); 
if (typeFromCombobox.Id == 0){ 
    //new type added 
    dbContext.Set<type>().Add(typeFromCombobox) 
} 
entity.type = typeFromCombobox; 
dbContext.SaveChanges() 
+0

Avec votre code, le nouveau type sera ajouté. Mais la clé étrangère de l'entrée n'est pas mise à jour dans la base de données. Je ne suis pas sûr de ce que vous voulez dire par "Détacher". Je ne suis plus dans le contexte que j'ai créé lors du chargement des entrées. – L3n95

+0

@ L3n95 vous voulez dire la clé étrangère 'entry.typeId'? Habituellement EF doit gérer cela lorsque vous faites l'affectation de la propriété de navigation –

+0

Oui. Avant la mise à jour: entry.type_id = 55, entry.type.id = 0; Après la mise à jour: entry.type_id = 55, entry.type.id = 56 – L3n95