Skip to content

Instantly share code, notes, and snippets.

@codelinq
Created January 26, 2011 20:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codelinq/797390 to your computer and use it in GitHub Desktop.
Save codelinq/797390 to your computer and use it in GitHub Desktop.
Make EFCachingProvider Support ambient transactions via TransactionScope.
public sealed class EFCachingCommand : DbCommandWrapper
{
// Modified this method to update the EFCachingEnlistment if it exists.
private void UpdateAffectedEntitySets()
{
if (this.transaction != null)
{
if (this.Definition.IsModification)
{
this.transaction.HasModifications = true;
}
foreach (EntitySetBase entitySet in this.Definition.AffectedEntitySets)
{
this.transaction.AddAffectedEntitySet(entitySet);
}
}
else if (this.Connection.Enlistment != null)
{
if (this.Definition.IsModification)
{
this.Connection.Enlistment.HasModifications = true;
}
foreach (EntitySetBase entitySet in this.Definition.AffectedEntitySets)
{
this.Connection.Enlistment.AddAffectedEntitySet(entitySet);
}
}
}
}
public class EFCachingConnection : DbConnectionWrapper
{
// Added the following property and method
internal EFCachingEnlistment Enlistment { get; set; }
public override void Open()
{
base.Open();
if (System.Transactions.Transaction.Current != null)
{
this.Enlistment = new EFCachingEnlistment {Cache = this.Cache, HasModifications = false};
System.Transactions.Transaction.Current.EnlistVolatile(this.Enlistment, EnlistmentOptions.None);
}
}
}
internal class EFCachingEnlistment : IEnlistmentNotification
{
private HashSet<EntitySetBase> affectedEntitySets = new HashSet<EntitySetBase>();
public EFCachingEnlistment()
{
HasModifications = false;
}
public void Commit(Enlistment enlistment)
{
if (Cache != null && this.HasModifications)
{
Cache.InvalidateSets(this.affectedEntitySets.Select(c => c.Name));
}
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
enlistment.Done();
}
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}
public void Rollback(Enlistment enlistment)
{
enlistment.Done();
}
internal void AddAffectedEntitySet(EntitySetBase entitySet)
{
this.affectedEntitySets.Add(entitySet);
}
public bool HasModifications { get; set; }
public ICache Cache { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment