gpt4 book ai didi

c# - 在 c# 控制台应用程序中启动 2 个 DBContext 对象,一个用于日志,另一个用于业务数据

转载 作者:太空狗 更新时间:2023-10-29 23:13:20 25 4
gpt4 key购买 nike

我正在开发一个 c# 控制台应用程序,我使用 Entity Framework 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();

现在我为我的日志提供了单独的 DbContext 对象,原因如下:-

  1. 如果我的第一个实体对象无法保存更改,由于任何原因,例如未处理的验证错误,或试图破解系统等。那么第二个实体对象仍然能够保存日志条目。让我们举个例子。假设我正在与第 3 部分 API 集成,我希望它们以特定格式返回 JSON。现在假设返回的 json 对象缺少数据,在这种情况下,当我尝试添加对象时,它将引发异常... 现在因为我有单独的日志实体对象,所以日志条目将被保存(不会受到任何业务数据异常的影响)。但是如果我只有一个 DBContext 对象,那么日志条目将无法保存,因为我无法保存业务数据。所以我的问题是,如果启动 2 个 DBContext 对象,一个用于日志,另一个用于业务数据,这是一种有效的方法跟随,还是跟随是一个错误的决定?

最佳答案

不要使用 2 个上下文,你应该使用一个记录器(例如 log4net with AdoNetAppender )。正如 Evk 在下面的评论中指出的那样,当您调用 SaveChanges() 时,EF 会自动将所有内容打包到一个事务中,因此一旦发生错误,就不会向数据库提交任何内容,您可以记录错误。例如:

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);
}
}
}

这样你的应用程序就会保持干净,只有当你在 using block 末尾调用 SaveChanges() 时一切都成功时你才会更新,并且只有当异常发生。此外,最好使用 using block 始终处理您的上下文,即使会发生意外异常。记录器将负责在另一个线程中将错误写入数据库,而不会减慢您的程序。也许你可以试试 NLog ,我听说它比 log4net 更好(=更易于配置/使用),但我仍然必须自己尝试一下。

关于c# - 在 c# 控制台应用程序中启动 2 个 DBContext 对象,一个用于日志,另一个用于业务数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36439784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com