问题摘要:我有一个 Master 和 Detail 实体。当我初始化一个 Master (myMaster) 时,它会创建一个 Details (myMaster.Detail) 实例,并且在添加 myMaster 时两者似乎都保留在数据库中。但是,当我重新加载上下文并访问 myMasterReloaded.detail 时,它的属性没有初始化。但是,如果我直接从上下文中提取细节,那么这似乎神奇地初始化了 myMasterReloaded.detail。我用下面的最小单元测试示例对此进行了提炼。这是一个“功能”还是我错过了一些重要的概念细节?
//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);
}
(这是更复杂实体集的症结所在。我只是将其简化为最简单的情况,我不能简单地用复杂类型替换细节)。
干杯,罗伯