2011-08-08 7 views
1

J'utilise EF4.1 Code First. Je ne peux pas obtenir une insertion très simple pour enregistrer l'ID d'entité associée. Le SQL généré insère toujours NULL pour toutes les entités associées. Exemple de code est ci-dessous. Quelqu'un peut-il voir ce que je fais mal ici? Il insère correctement les propriétés non-entité, telles que les chaînes. J'ai aussi un code similaire dans une classe d'initialisation DB pour graver des données de test et cela semble fonctionner correctement.Code EF4.1 Première entité Ajouter une entité associée

 using (var ctx = new DataContext()) 
     { 
      ctx.Users.Attach(existingUser); 

      // create item and add to context 
      var newItem = new MyItem(); 
      ctx.MyItems.Add(newItem); 

      // set related entity 
      newItem.CreatedBy = existingUser; 

      ctx.SaveChanges(); 
     } 

Répondre

1

Votre code devrait fonctionner avec la configuration par défaut de votre DbContext. Une explication possible que cela ne fonctionne est que vous n'avez pas la détection automatique changement désactivé, par exemple si vous avez dans le constructeur de quelque chose comme votre contexte:

public DataContext() 
{ 
    this.Configuration.AutoDetectChangesEnabled = false; 
} 

Dans ce cas, EF ne détecte pas le changement de la propriété de navigation newItem.CreatedBy après avoir ajouté le nouvel élément au contexte. (SaveChanges détecterait ce dernier changement si la détection de changement n'est pas désactivé.)

Vous pouvez modifier votre code afin que définir la propriété de navigation se produit avant d'ajouter le nouvel élément au contexte:

using (var ctx = new DataContext()) 
{ 
    ctx.Users.Attach(existingUser); 

    // create item and add to context 
    var newItem = new MyItem(); 

    // set related entity 
    newItem.CreatedBy = existingUser; 

    ctx.MyItems.Add(newItem); 

    ctx.SaveChanges(); 
} 

Cette devrait fonctionner avec et sans détection automatique des changements.

+0

J'ai effectivement changé la valeur de détection à false. Et déplacer le code comme indiqué ci-dessus a résolu le problème. Merci pour l'aide. Je suppose qu'il doit aussi y avoir un moyen de marquer la propriété telle que modifiée? Qu'en est-il du cas où votre mise à jour d'une entité existante. –

+0

Il apparaît quelque chose comme ceci: 'ctx.Entry (existingItem) .State = EntityState.Modified' est la solution dans le cas d'une entité existante attachée. –

+0

@Barry: Sachez que définir manuellement l'état sur 'Modified' provoque une instruction SQL * full * update: * Toutes les propriétés * seront envoyées au serveur, qu'elles aient vraiment changé ou non. Souvent, il peut être préférable (en termes de performances) de récupérer l'objet d'origine dans la base de données et de fusionner les propriétés modifiées. EF suivra ces modifications et n'a envoyé qu'une commande de mise à jour avec les propriétés réellement modifiées. – Slauma

0

Essayez ceci:

using (var ctx = new DataContext()) 
{ 
    ctx.Users.Attach(existingUser); 

    // create item and add to context 
    var newItem = new MyItem(); 
    ctx.MyItems.Add(newItem); 

    // set related entity 
    newItem.CreatedBy = existingUser; 

    // Added 
    ctx.ObjectStateManager.ChangeObjectState(newItem.CreatedBy, EntityState.Added); 

    ctx.SaveChanges(); 
} 

Si cela ne fonctionne pas, modifiez la ligne avec:

ctx.ObjectStateManager.ChangeObjectState (newItem.CreatedBy, EntityState.Modified);

Ajouté 1 ligne ... J'espère que ça aide.

Questions connexes