次の状況を考慮してください。
public class EntityA
{
public int Id { get; set; }
}
public class EntityB
{
public int Id { get; set; }
public virtual EntityA EntityA { get; set; }
}
public class Context : DbContext
{
public Context()
: base("EF_SPIKE")
{
}
public IDbSet<EntityA> EntityAs { get; set; }
public IDbSet<EntityB> EntityBs { get; set; }
}
static void Main(string[] args)
{
using (var context = new Context())
{
var a = context.EntityAs.Create();
context.EntityAs.Add(a);
var b = context.EntityBs.Create();
b.EntityA = a;
context.EntityBs.Add(b);
context.SaveChanges();
using (var transaction = new TransactionScope())
{
context.EntityBs.Remove(b);
context.SaveChanges();
}
Trace.Assert(b.EntityA == null);
Trace.Assert(context.EntityBs.Local.All(x => x.Id != b.Id));
Trace.Assert(context.EntityBs.Any(x => x.Id == b.Id));
}
}
そのため、トランザクションはロールバックされ、エンティティはデータベースにまだ存在しますが、エンティティ フレームワーク エンティティb
はローカル キャッシュに存在しなくなり、すべての外部キー参照が失われ、操作b
できなくなります。
ロールバックしたにもかかわらず、エンティティがまだ死んでいるので、この動作は奇妙に思えます。
これに対する標準的な回避策はありますか:
Trace.Assert(context.EntityBs.Local.Any(x => x.Id == b.Id));
合格?