Problème: J'ai des entités maître et de détail. Lorsque j'initialise un maître (myMaster), il crée une instance de Details (myMaster.Detail) et les deux semblent persister dans la base de données lors de l'ajout de myMaster. Cependant, lorsque je recharge le contexte et accède à myMasterReloaded.detail ses propriétés ne sont pas initialisées. Cependant, si je tire directement le détail du contexte, cela semble magiquement initialiser myMasterReloaded.detail. J'ai distillé ceci avec un exemple de test unitaire minimal ci-dessous. Est-ce une "caractéristique" ou manque-t-il des détails conceptuels importants?Problème d'enregistrement avec Entity Framework (besoin d'aide conceptuelle)
//DECLARE CLASSES
public class Master
{
[Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
public Guid MasterId { get; set; }
public Detail Detail { get; set; }
public Master() { Detail = new Detail(); }
}
public class Detail
{
[Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
public Guid DetailId { get; set; }
public Master MyMaster{ get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<Master> Masters { get; set; }
public DbSet<Detail> Details { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Master>()
.HasOptional(x => x.Detail)
.WithOptionalPrincipal(x => x.MyMaster)
.WillCascadeOnDelete(true);
}
}
//PERFORM UNIT TEST
[TestMethod]
public void UnitTestMethod()
{
//Start with fresh DB
var context = new MyDbContext();
context.Database.Delete();
context.Database.CreateIfNotExists();
//Create and save entities
var master = context.Masters.Create();
context.Masters.Add(master);
context.SaveChanges();
//Reload entity
var contextReloaded = new MyDbContext();
var masterReloaded = contextReloaded.Masters.First();
//This should NOT Pass but it does..
Assert.AreNotEqual(master.Detail.DetailId, masterReloaded.Detail.DetailId);
//Let's say 'hi' to the instance of details in the db without using it.
contextReloaded.Details.First();
//By simply referencing the instance above, THIS now passes, contracting the first Assert....WTF??
Assert.AreEqual(master.Detail.DetailId, masterReloaded.Detail.DetailId);
}
(C'est le point d'achoppement pour un ensemble d'entités plus sophistiqué. Je l'ai simplement distillée, jusqu'à son cas le plus simple, je ne peux pas remplacer simplement les détails d'un type complexe).
Cheers, Rob
Cela et le fait que tout nouveau maître créera automatiquement un nouveau détail (dans son ctor), chargeant ainsi un maître de la base de données va essayer de créer une nouvelle instance de détail. –
À moins que EF4 ne contourne en quelque sorte le ctor par défaut lors de l'instanciation d'entités. Tout est possible je suppose. –
Yup. Ne devrait pas être la création d'entités dans le ctor. Laissez EF faire ce pour quoi il a été conçu. – RPM1984