EF事务c#MySQL连接器
我想知道实现以下目标的最佳方式或实践是什么: 我有一个名为EditUser的方法,它具有以下定义:EF事务c#MySQL连接器,c#,mysql,entity-framework-4,transactions,transactionscope,C#,Mysql,Entity Framework 4,Transactions,Transactionscope,我想知道实现以下目标的最佳方式或实践是什么: 我有一个名为EditUser的方法,它具有以下定义: public void EditUser(user user, Roles role) { using (TestEntities entities = new TestEntities()) { entities.Connection.Open(); using (DbTransaction trans =
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;
}
}
}
}
正如您可能注意到的,我正在调用几个方法:UnbindRoles、DeleteUser和RegisterUser,其中所有方法都需要在同一事务(EditUser正在运行的同一事务)下运行,如果出现故障,我将需要回滚
现在我的问题主要在这里…方法RegisterUser还启动一个新事务,因为它添加了一个用户并为新用户分配了一个角色
谁能描述一下实现这一点的最佳方式?我尝试使用TransactionScope块,但失败了,因为我正在中等信任环境中运行此应用程序
编辑
确认MySQL.NET连接器提供程序在中等信任下使用TransactionScope时存在错误,因为我刚刚使用MS SQL Server数据库测试了相同的场景,并且它可以正常工作是否可以对现有事务进行注册检查,如果不存在事务,则仅创建一个?这就是嵌套TransactionScope在类似情况下所做的。如果我理解正确,您遇到的问题是,您对DeleteUser和RegisterUser的调用正在启动新事务,需要在当前事务中登记 解决此问题的几种方法: A) 当您创建transactionscope时,您可以说他们只需要在没有可用transactionscope的情况下创建一个transactionscope B) 与第一种方法不同的是,引入私有方法,比如InnerEdit和InnerRegister,它们包含逻辑,但不打开或关闭代码保留在公共可用的Edit和Register方法中的任何事务。这些“内部”方法可以重用,而公共方法包含基础结构。如果你在面向方面的编程中使用google的第二种方法,那么它可以解决这些“交叉关注点”
public void EditUser(user user, Roles role)
{
using (TestEntities entities = new TestEntities())
{
entities.Connection.Open();
using (DbTransaction trans = entities.Connection.BeginTransaction())
{
InnerEditUser(entities, trans);
InnerThat(entities, trans);
InnerThis(entities,trans);
entities.SaveChanges();
trans.Commit();
}
}
}
关于另一个话题:哦,不!掷骰子!!!除非您真的想丢失stacktracke,否则您应该执行throw。调用方正在捕获该throw并再次抛出它,以便Application_Error事件中的Global.asax将对错误进行一般处理,只是确保您知道throw之间的区别;然后扔掉它;是的,这是一个选项,但我一开始就在想,这个选项是某种“修补工作”,这本质上就是TransactionScope所做的工作——如果存在环境事务,它会登记在环境事务中,否则会创建一个新的事务。由于您不能使用TransactionScope,因此您只能自己执行此操作。如果你把它很好地包装在一个方法中,我觉得它是合法的。我不确定你是从哪里得到userFromDb EntityObject下的ChangeRole方法的,你能解释一下吗?或者你创建的那些用户和角色类?然后,我会为它们添加功能以适应当前的问题。但问题是,在每个方法中,我都在保存更改(调用entities.SaveChanges()),因为有时我需要手动调用ChangeRole或AddUser方法(而不被EditUser或RegisterUser调用)这就是为什么我需要有一个事务,这样我就可以根据发生的事情提交或回滚Hanks mate,我很感激,因为我已经被困在这个问题上两天了,我已经尝试再次使用TransactionScope,并且由于我在中等信任度下运行,所以在EnstractTransaction方法上发生了错误,知道为什么吗?