【问题标题】:Proper way to use dbcontext (Global or pass as parameter?)使用 dbcontext 的正确方法(全局或作为参数传递?)
【发布时间】:2015-09-09 06:16:54
【问题描述】:

当我为updateinsert 调用需要dbcontext 的方法时 但只想要一个saveChange() 喜欢关注

操作:登录

        TempDBEntity context = new TempDBEntity();
        var temp = context.Users.Where(m => m.user_unique_id == 1).FirstOrDefault();
        temp.timestamp = new DateTime();
        temp.AddLog("Login");
        context.SaveChanges();

功能:添加日志

public void AddLog(string activity){
        TempDBEntity context2 = new TempDBEntity();
        var log = new UserLog();
        log.user_id = this.user_id;
        log.activity = activity;
        context2.UserLog.Add(log);
        context2.SaveChanges();
 }

如您所见,有两个SaveChanges(),我只需要一个SaveChanges()

我是否应该将DBContext 作为AddLog() 的另一个参数传递 或者在这种情况下我应该为dbcontext声明静态变量吗?

非常感谢。

【问题讨论】:

  • 不调用第一个 savechanges() 怎么样
  • 不先调用 savechange?那么就不会添加了。
  • 我认为将上下文作为参数传递会比将其声明为静态变量更好。
  • 但在实际应用中,有很多方法存在这种冲突。我是否必须将参数传递给所有这些方法?
  • 除非您的网站只供 one 人使用,否则静态变量并不是正确的解决方案。几乎所有的 asp.net 网站都会被 多个 用户同时使用 - 你不希望他们都共享 same 上下文对象。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

在你的情况下,我会在你需要的方法中创建一个新的 dabtase 上下文,因为这是最简单的方法,你可以很好地重用你的方法。

这应该不会造成很多性能问题,因为实体框架会将所有重要信息缓存在数据库上下文中,因此创建一个新的非常快。

如果你想优化事务的数量,我会编写一种处理程序,它实现它自己的SaveChanges 方法并为每个实例保存一个数据库上下文。比你多了一个抽象层和一个不错的 API 供以后使用。

这是一个简单的例子:

class UserLogin
{
    private TempDBEntity dbContex;

    UserLogin()
    {
        // ctor create dbContext
    }

    void Login()
    {
        // Login...
    }

    void AddLog()
    {
        // ...
    }

    void SaveChanges()
    {
        //dbContext.SaveChanges()...
    }
}

在我看来,将 dbcontext 作为参数传递不是一个很好的解决方案。但这是基于意见的......

【讨论】:

  • 这似乎是更典型的方法。我不喜欢传递数据上下文的想法,而且我还没有在我处理过的任何生产代码中看到这样做。
  • 使用我的解决方案,您不会传递任何数据上下文,这就是想法。您有一个 UserLogin 实例(例如一个请求)。因为 UserLogin 包含数据上下文,所以您只有一个...
【解决方案2】:

您可以按如下方式使用 dbcontext:

操作:登录

using(TempDBEntity context = new TempDBEntity())
{
   var temp = context.Users.Where(m => m.user_unique_id == 1).FirstOrDefault();
   temp.timestamp = new DateTime();
   temp.AddLog("Login", context);
}

功能:添加日志

public void AddLog(string activity, TempDBEntity context)
{
    var log = new UserLog();
    log.user_id = this.user_id;
    log.activity = activity;
    context.UserLog.Add(log);
    context.SaveChanges(); 
}

这将在使用后正确处理对象。

【讨论】:

  • 很好,但我会将SaveChanges() 放在主要方法级别。
  • 我对此持怀疑态度,我希望看到更多的赞成票来确信这是真的——通常将 IDisposable(尤其是 DbContext)传递给函数仍然可以正确处理.但我相信——毕竟,为什么不呢? -- 这就是 using 块的威力。即使发生异常,它也会被处理掉。但是,除了通过不是您自己创建的 DbContext 的“奇怪”之外,还有其他后果吗?
  • 还想知道@tschmit007 的评论...我猜...如果您不负责创建 DbContext,我猜您不应该保存。单个SaveChanges() 不像事务一样工作,即自最近的SaveChanges() 以来围绕任何实体框架更改的事务?不确定我是否相信一种方法来决定何时“提交”交易——但如果我用我的 DbContext 信任它,我想我会相信它来决定何时 SaveChanges()!
  • @TheRedPea 通常我使用一个存储库来封装/屏蔽 dbcontext。存储库允许业务层对存储库执行/声明一项或多项操作(在一个事务中)。当业务层完成操作时,它会声明对 repo 的提交。
【解决方案3】:
I think you don't need to create new context in your AddLog function, you can pass the same first context to your AddLog function and then add your UserLogs to that without calling savechanges like this-

public void AddLog(TempDBEntity context, string activity){
        var log = new UserLog();
        log.user_id = this.user_id;
        log.activity = activity;
        context.UserLog.Add(log);
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2012-02-10
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多