I was wondering what is the best way or practice to implement the following:
I have a method called EditUser which has the following definition:
public void EditUser(user user, Roles role)
{
using (TestEntities entities = new TestEntities())
{
entities.Connection.Open();
using (DbTransaction trans = entities.Connection.BeginTransaction())
{
try
{
var tmpUser = entities.users.Where(fields => fields.UserId == user.UserId).FirstOrDefault();
RoleManagement rm = new RoleManagement();
string oldRole = tmpUser.roles.FirstOrDefault().Name;
string newRole = rm.GetRoleName(role);
if (oldRole == newRole)
{
entities.users.ApplyCurrentValues(user);
}
else
{
rm.UnbindRoles(tmpUser.UserId, entities.Connection);
this.DeleteUser(tmpUser.UserId, entities.Connection);
this.Register(user, role, entities.Connection);
}
entities.SaveChanges();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
}
}
As you may notice I am calling several methods: UnbindRoles, DeleteUser and RegisterUser where all of them need to be running under the same transaction (the same transaction the EditUser is running) in case something fails I will need to rollback.
Now my problem is mostly here...the method RegisterUser also starts a new transaction since it adds a user and assign the new user a role.
Can anyone describe the best way how to implement this? I tried using a TransactionScope block but it fails since I am running this application in a Medium Trust environment
EDIT
Confirming that the MySQL .NET connector provider has a bug when using TransactionScope under Medium Trust since I have just tested now the same scenario using a MS SQL Server database and it works without any problems