【发布时间】:2016-10-13 18:39:56
【问题描述】:
我正在处理实体框架 4,因为应用程序已经构建,我必须在其中进行一些渐变。
场景: 在我的代码中实现了一个 DBTransaction(在数据库中插入数据),一旦一个事务在中途中止并回滚执行,那么下次当相同的事务使用正确/验证的数据执行时,事务仍然通过给出先前的异常中止。很难理解,因为我认为 RollBack 应该从数据库上下文中删除验证消息和数据,因为它是 SQL。 注意:我一直在使用静态 DatabaseContext。
public class TestClass
{
static SampleDataBaseEntities ctx = new SampleDataBaseEntities();
public void SqlTransaction()
{
ctx.Connection.Open();
using (DbTransaction transaction = ctx.Connection.BeginTransaction())
{
try
{
Student std = new Student();
std.first_name = "first";
//std.last_name = "last"; (This is responsible for generating the exception)
AddTeacher();
ctx.AcceptAllChanges();
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
}
finally
{
ctx.Connection.Close();
}
}
}
public void SqlTransaction2()
{
ctx.Connection.Open();
using (DbTransaction transaction = ctx.Connection.BeginTransaction())
{
try
{
Student std = new Student();
std.first_name = "first";
std.last_name = "last";
AddTeacher();
ctx.Students.AddObject(std);
ctx.SaveChanges(false);
transaction.Commit();
ctx.AcceptAllChanges();
}
catch (Exception e)
{
transaction.Rollback();
transaction.Dispose();
ctx.Connection.Close();
}
}
}
public void AddTeacher()
{
Teacher t = new Teacher();
t.first_name = "teacher_first";
t.last_name = "teacher_last";
t.school_name = "PUCIT";
ctx.Teachers.AddObject(t);
ctx.SaveChanges(false);
}
}
class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass();
test.SqlTransaction();
test.SqlTransaction2();
}
}
解决方案(我已经尝试过): 使用 SaveChanges(false)。 使用 SaveChanges(false) 和 ctx.AcceptAllChanges()。
解决方法: 我得到的解决方法是重新实例化 DatabaseContext 对象。
由于我在重新实例化上下文时遇到了复杂性问题,这就是为什么要寻找更合适的解决方案。 提前致谢。
【问题讨论】:
-
不要使用静态 DatabaseContext。根据需要创建一个。此外,您不需要手动处理 SQL 事务。
-
什么是“重新实例化上下文的复杂性问题”?
-
不要使用静态 DbContext,因为它不是线程安全的。还要始终使用
using语句,这样如果出现任何问题,上下文将回滚任何更改。 -
尽可能晚地创建上下文并尽快处理它(使用 using!)。当然不是静态的。如果您有“复杂性问题”,请首先解决这些问题;然后以正确的方式使用上下文,正如其他人之前提到的那样。
-
实际上在应用程序中,上下文是在构造函数中创建的,并在整个应用程序中使用。这是使用上下文对象的正确方法吗?