我使用 Entity Framework
连接数据库。我实现了一个联系人存储库来保存联系信息(示例存储库)。在Said类文件中,我声明static property
用于处理DBEntities
(即BLabsEntities
)即“Context
”,并为{{static property
声明了DbContextTransaction
1}}。
在下面的代码中,我添加了一个try catch块来处理SaveContact()
Repository方法中的Entity Framework异常。我在上述方法中启动Save Contact过程之前启动了transaction
,然后根据我的想法将dbo.Contact
添加到数据库表exception
中。在Catch块中,我正在启动所述事务的Rollback
进程,我正在尝试在ErrorLog Table
中插入Exception消息,但Context属性保存了Contact信息 - 尽管回滚过程执行。 因此,在尝试在dbo.ErrorLog Table
中插入记录时,它会再次在catch块中抛出异常。我添加了一个调试快照供您参考。
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace EF_Sample
{
public class ContactRepository
{
private static BLabsEntities _context;
private static DbContextTransaction _dbTransaction;
protected static BLabsEntities Context
{
get { return _context ?? (_context = new BLabsEntities()); }
}
protected static DbContextTransaction DBTransaction
{
get { return _dbTransaction; }
set { _dbTransaction = value; }
}
public void SaveContact(Contact contact = null)
{
try
{
if (contact == null)
{
contact = new Contact()
{
FirstName = null,
LastName = null
};
}
BeginTransaction();
Context.Contacts.Add(contact);
Context.SaveChanges();
}
catch (Exception ex)
{
CommitTransaction(false);
BeginTransaction();
ErrorLog error = new ErrorLog()
{
Message = ex.Message
};
Context.ErrorLogs.Add(error);
Context.SaveChanges();
}
finally
{
CommitTransaction();
}
}
private void BeginTransaction()
{
DBTransaction = Context.Database.BeginTransaction();
}
private void CommitTransaction(bool flag = true)
{
try
{
if (flag)
{
DBTransaction.Commit();
}
else
{
DBTransaction.Rollback();
}
}
catch (Exception Ex)
{
Console.WriteLine("Error: {0}", Ex.Message);
}
}
}
}
调试快照:
try Block
中的异常:代码明确创建的异常
Catch Block
中的例外:Rollback
操作失败
数据库表结构:
请帮助我成功完成Rollback
操作,以清除上下文更改。
答案 0 :(得分:1)
实际答案可能更简单:
https://github.com/aspnet/EntityFramework.Docs/issues/327
在大多数情况下,无需显式调用dbContextTransaction.Rollback(),因为在using块末尾放置事务将有助于回滚。
如果SQL Server中发生足够严重的错误,则 交易将自动回滚,并且对 catch块中的dbContextTransaction.Rollback()实际上会失败。