Entity Framework ne détectera pas les modifications des propriétés de navigation
Je vais avoir des problèmes avec la détection des changements d'une propriété de navigation:
Mon modèle de test ressemble à ceci:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public string Name { get; set; }
}
J'ai créé et enregistré un objet de type Personne à la fois le Nom et l'Adresse des propriétés affectées. Mon problème est que si je récupère la Personne objet de la base de données et j'ai changer l'Adresse de la propriété (ex. Null) puis, l'e.f. ne détecte pas le changement!
Mon code est: est-ce
using (var ctx = new EFContext())
{
Person p = ctx.People.First();
//p.Address IS NOT NULL!
p.Address = null;
var entry = ctx.Entry(p);
}
Pourquoi est entry.State
Inchangé ?
Edit: Si je l'appelle le SaveChanges, l'enregistrement est enregistré correctement (l'Adresse nulle)!
Edit 2: j'ai créé la clé étrangère de la propriété que billy a suggéré, et si je l'inspecter la Personne objet dans visual studio, l'État est Modifié.. si je ne m'arrête pas avec le débogueur de l'inspection l'objet de valeurs de l'état est Inchangé!
Edit 3: Chargement de la Personne objet à l'aide de ctx.Personnes.Inclure(x => x.L'adresse).First(); permet de résoudre le problème. Est-il un moyen pour éviter l'appel d'Inclure et de continuer à modifier l'Adresse de la propriété au lieu de la AddressId?
source d'informationauteur Mones
Vous devez vous connecter pour publier un commentaire.
Tout d'abord: Vous DEVEZ suivre @billy conseils d'utilisation
Include
. Votre remarque "p.L'adresse n'EST PAS NULLE!" n'est vrai que parce que vous regardezp.Address
dans le débogueur et ce qui déclenche le chargement paresseux dans le débogueur, de sorte que le changement de réglage de l'adresse denull
est détecté. En mode release, ou lorsque vous n'avez pas de vérifier les propriétés dans le débogueur votre code ne fonctionne pas et aucune modification ne serait sauvé.Donc, la réponse à votre Edit 3: No.
Deuxième:
var entry = ctx.Entry(p)
ne renvoie entité états et vous n'avez pas à modifier un état de l'entité, mais plutôt un relation de l'étatou plus précisément, vous supprimé une relation. Vous ne pouvez pas inspecter les relations des états avec leDbContext
API, mais seulement avec laObjectContext
API:objentr
aura une entrée de typeRelationshipEntry
maintenant:EF tiendra compte de cette relation entrée avec une entité de l'état des entrées lorsque vous appelez
SaveChanges()
et de supprimer la relation, c'est à dire définir laAddress
colonne de clé étrangère de laPerson
dans la base de données deNULL
.Sur Edit 2: la Modification d'une propriété de clé étrangère (ce qui est une propriété scalaire dans votre modèle) est une modification de l'entité elle-même, de sorte que l'état de l'entité sera
Modified
dans ce cas.Vous devez inclure l'Adresse de la valeur liquidative. prop. dans votre requête, sinon EF n'envisage pas de modifications lorsque vous enregistrez :
Vous pouvez également utiliser des clés étrangères dans votre modèle, que j'aime beaucoup :
...
Dans mon application, avant un renouvellement est demandé ou l'utilisateur quitte l'élément/la vue, j'ai effectuer des vérifications pour s'assurer il n'y a pas de modifications non enregistrées.
C'est essentiellement en marche hors de la actuellement accepté de répondre, mais je voulais donner une mise en œuvre et de porter à l'attention que vous devez appeler
Context.ChangeTracker.DetectChanges()
avant laObjectContext.ObjectStateManager
pouvez ramasser relation change! J'ai passé un peu de temps de débogage ce, idiot!