私のプロジェクトには古い ObjectContext といくつかの新しい DbContext があります (つまり、さまざまな目的のための BoundedContext です)。いくつかの変更を 1 回のトランザクションでコミットする必要がある場合があります。場合によっては、ObjectContext と DbContext からのデータを保持する必要があります。EF 5.0 では、MSDC を回避するためにいくつかのラッパーを作成します
public class ContextUnitOfWork
{
List<IContext> ContextList;
public ContextUnitOfWork()
{
ContextList = new List<IContext>();
}
public void RegisterContext(IContext Context)
{
ContextList.Add(Context);
}
public bool IsDisposed
{
get
{
return ContextList.Any(x => x.IsDisposed);
}
}
public bool HasChangedEntities
{
get
{
return ContextList.Any(x => x.HasChangedEntities);
}
}
public void Commit()
{
bool HasDbContext = ContextList.OfType<System.Data.Entity.DbContext>().Any();
try
{
if (HasDbContext)
{
ContextList.ForEach(x =>
{
if (x is System.Data.Entity.DbContext)
{
(x as System.Data.Entity.DbContext).Database.Connection.Open();
}
else if (x is System.Data.Objects.ObjectContext)
{
((System.Data.Objects.ObjectContext)x).Connection.Open();
}
});
}
using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required,
new System.Transactions.TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
{
ContextList.ForEach(x => x.Commit());
scope.Complete();
}
}
catch (System.Data.UpdateException uex)
{
var ErrorList = uex.StateEntries.Select(x => x.Entity).ToList();
}
finally
{
if (HasDbContext)
{
ContextList.ForEach(x =>
{
if (x is System.Data.Entity.DbContext)
{
(x as System.Data.Entity.DbContext).Database.Connection.Close();
}
else if (x is System.Data.Objects.ObjectContext)
{
((System.Data.Objects.ObjectContext)x).Connection.Close();
}
});
};
}
}
}
しかし、EntityFramework 6.0.1 では機能しません。ObjectContext は正常にコミットされますが、DbContext が SaveChanges() を呼び出すと、タイプEntityExceptionの Exception がテキスト「The 基本プロバイダーが EnlistTransaction で失敗しました。」また、Inner Expection には、{"分散トランザクション マネージャー (MSDTC) のネットワーク アクセスが無効になっています。コンポーネント サービス管理ツールを使用して、MSDTC のセキュリティ構成でネットワーク アクセスの DTC を有効にしてください。 "}
1 つのトランザクションでコンテキストをコミットし、MDTC 例外を回避するためのアイデアはありますか?