joh*_* Gu 5 c# ado.net entity-framework dbcontext entity-framework-5
我正在研究ac#console应用程序,我使用实体框架5.0作为sql server的数据访问层.现在我想跟踪更改并将它们保存在日志表中.所以这样做我发起了2个DbContext对象,一个用于业务数据,另一个用于日志数据,如下所示:
class Sync
{
static void Main(string[] args)
{
string syncResult = "Sync started";
Entities entities = new Entities();//for business data
Entities entities2 = new Entities();//for logs
try
{
//code goes here
entities.SaveChanges();
}
catch (Exception e)
{
syncResult = string.IsNullOrEmpty(e.Message) ? "Error" : e.Message;
}
entities.Dispose();
entities2.LogHistories.Add(new LogHistory() { Description = syncResult });
entities2.SaveChanges();
entities2.Dispose();
Run Code Online (Sandbox Code Playgroud)
现在我为我的日志提供了单独的DbContext对象,原因如下: -
不要使用2个上下文,您应该使用记录器(例如使用AdoNetAppender的log4net).正如Evk在下面的评论中指出的那样,EF会在您调用时自动将所有内容包装到事务中SaveChanges(),因此一旦发生错误,就不会向数据库提交任何内容,您可以记录错误.例如:
static void Main(string[] args)
{
ILog log = LogManager.GetLogger("Entities");
using(var ctx = new Entities())
{
try
{
...
ctx.SaveChanges();
}
catch(Exception ex)
{
log.Error(ex.Message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您的应用程序保持干净,只有SaveChanges()在using块结束时调用一切都成功时才会更新,并且仅在发生异常时进行记录.即使发生意外异常,使用块总是处理您的上下文也会更好.记录器将负责将错误写入另一个线程中的数据库,而不会降低程序的速度.也许你可以试试NLog,我听说它比log4net更好(=更容易配置/使用),但我还是要自己尝试一下.
如果您的数据库包含多个数据库模式并且您希望将每个数据库模式作为单独的自包含区域进行处理,则为单个数据库拥有多个上下文可能会很有用。如果是这种情况,从您的代码/要求中不清楚。
如果您正在使用的表位于相同的数据库和相同的架构中,那么我看不出您使用两个 DbContext 的理由。即使出现验证错误或异常,您仍然可以使用相同的上下文保存到日志表中。
如果您尝试记录错误和/或其他相关信息,为什么不使用 log4net 来进行日志记录呢?
编辑
在我看来,日志记录应该独立于您的正常事务,因此您不必考虑这种情况。话虽这么说,在事务中您可以保存并记录,而且如果出现异常也可以记录。除非我遗漏了什么,否则我仍然认为不需要 2 个 DBContext。
请查看以下内容,了解有关交易的一些指导。
https://msdn.microsoft.com/en-us/data/dn456843.aspx