您好我正在尝试将事务与实体框架一起使用。由于在线提供了大量有关实施交易的不同方式的信息,我必须说我在正确的方式上有点困惑。我有一个带有两个表Employee和Company的示例数据库。 Employee表有一个引用公司Id的外键。考虑到我想实现一个事务,我将一条记录插入到Company表中,然后将记录插入到Employee表中,我想这样做,以便只有两个记录都成功时才插入记录我有以下代码。
public void addCompanyToDatabase()
{
using (var context = new myTestEntities())
{
context.Connection.Open(); //added this as was getting the underlying
//provider failed to open
using (TransactionScope scope = new TransactionScope())
{
try
{
Company c = new Company();
c.Name = "xyz";
context.Companies.AddObject(c);
context.SaveChanges();
//int a = 0;
//int b = 5 / a;
Employee e = new Employee();
e.Age = 15;
e.Name = "James";
e.CompanyId = c.Id;
context.Employees.AddObject(e);
context.SaveChanges();
scope.Complete();
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred");
}
}
}
}
我想知道这是否是实施交易的正确方法。如果是,那么SaveChanges(false)
和scope.AcceptAllChanges()
函数的用途是什么。任何信息都会有所帮助。
答案 0 :(得分:14)
在您的情况下,您不需要管理任何连接或事务:实体框架将为您执行此操作。当您不为EF提供已打开的连接(但使用连接字符串)时,它将打开一个连接并在调用context.SaveChanges()
期间启动一个事务。在该呼叫期间发生故障时,将回滚该事务。
换句话说,您的方法可能只是这样:
public void addCompanyToDatabase()
{
using (var context = new myTestEntities())
{
Company c = new Company();
c.Name = "xyz";
context.Companies.AddObject(c);
Employee e = new Employee();
e.Age = 15;
e.Name = "James";
e.CompanyId = c.Id;
context.Employees.AddObject(e);
// Only call SaveChanges last.
context.SaveChanges();
}
}
答案 1 :(得分:0)
1 <此服务(我认为交易服务)必须在客户端运行才能支持TransactionScope
2 - 在您的应用程序中有两个或更多数据库并且您希望所有数据库更新事务性(例如更改上下文的连接字符串)时有用。
3 - 当你拥有一个数据库时,最好使用内部实现事务的SaveChanges()。