1

次の状況を考慮してください。

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));

合格?

4

0 に答える 0