問題の概要:マスター エンティティと詳細エンティティがあります。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);
}
(これは、より洗練されたエンティティ セットの難点です。詳細を単純に複雑な型に置き換えることができない最も単純なケースにこれを単純に要約しました)。
乾杯、ロブ