C#(MVC3)中静态(扩展)类中动态属性的行为是什么 我是在.NET和C语言开发的新手,但一直是一个长期开发人员,用C、C++、java、PHP等。

C#(MVC3)中静态(扩展)类中动态属性的行为是什么 我是在.NET和C语言开发的新手,但一直是一个长期开发人员,用C、C++、java、PHP等。,c#,asp.net-mvc-3,entity-framework,static,C#,Asp.net Mvc 3,Entity Framework,Static,我的数据模型有一个MVC3扩展类,它引用数据库。它在类中被设置为“private static”,但我认为它不能跟上数据库的变化。换句话说,当我更改控制器中的数据时,这些更改在数据库中不会被“注意”,因为它是静态的。目前,我正在为每次使用创建和处理变量,以进行补偿 我的问题是: 静态db变量的这种行为正确吗 是否有必要在静态类中处理动态变量,或者垃圾收集仍然会自动处理它 以下是该类的相关片段: namespace PBA.Models { using System; using

我的数据模型有一个MVC3扩展类,它引用数据库。它在类中被设置为“private static”,但我认为它不能跟上数据库的变化。换句话说,当我更改控制器中的数据时,这些更改在数据库中不会被“注意”,因为它是静态的。目前,我正在为每次使用创建和处理变量,以进行补偿

我的问题是:

  • 静态db变量的这种行为正确吗
  • 是否有必要在静态类中处理动态变量,或者垃圾收集仍然会自动处理它
  • 以下是该类的相关片段:

    namespace PBA.Models {
        using System;
        using System.Text.RegularExpressions;
        using PBA.Models;
        using PBA.Controllers;
    
        public static class Extensions {
            private static PbaDbEntities db = null;
    
            public static PbaDbEntities GetDb() {
                // TODO: find out about static memory/disposal, etc.
                //
                if (db != null) {
                    db.Dispose();
                }
                db = new PbaDbEntities();
                return db;
            }
    
            public static string GetCheckpointState(this Activity activity, long memberProjectId) {
                GetDb();  // TODO: Do I need to do this each time, or will a one-time setting work?
    
                string state = CheckpointController.CHECKPOINT_STATUS_NOT_STARTED;
                try {
                    var sub = db.ActivitySubmissions.
                        Where(s => s.activityId == activity.activityId).
                        Where(s => s.memberProjectId == memberProjectId).
                        OrderByDescending(s => s.submitted).
                        First();
                    if (sub != null) {
                        state = sub.checkpointStatusId;
                    }
                }
                catch (Exception e) {
    // omitted for brevity
                    }
                    return state;
                }
            }
        }
    

    您的代码将在生产中严重失败。
    数据上下文不是线程安全的;您不能在请求之间共享上下文


    在多线程应用程序中,切勿将可变对象放在静态字段中。

    您的代码将在生产中严重失败。
    数据上下文不是线程安全的;您不能在请求之间共享上下文


    在多线程应用程序中,永远不要将可变对象放在静态字段中。

    以这种方式忽略异常是个糟糕的主意,如果您不想处理异常,请不要尝试/catch或catch&rethrow。这样考虑一下,在您掩埋了异常之后,您的程序处于无效状态,b/c一些您无法控制的错误被排除。现在,b/c您已经隐藏了异常,您的程序可以继续运行,但它处于一个糟糕的状态

    如果你的代码能够投入生产,3.5年后,一些jr程序员会卷入半夜的风暴,因为网站突然被破坏了,即使它曾经工作过。追踪异常发生的位置是完全不可能的,因此,这个可怜的家伙将连续48小时在各地添加日志代码来追踪问题。他会发现某处的DBA决定将列MemberProjectId重命名为MemberProjectIdentifier,这导致linq崩溃

    想想孩子,处理例外,不要埋葬他们


    顺便说一句,是的,我就是那个必须找出这些类型错误的人。

    以这种方式忽略异常是个糟糕的主意,如果你不想处理异常,就不要尝试/catch,或者catch&rethrow。这样考虑一下,在您掩埋了异常之后,您的程序处于无效状态,b/c一些您无法控制的错误被排除。现在,b/c您已经隐藏了异常,您的程序可以继续运行,但它处于一个糟糕的状态

    如果你的代码能够投入生产,3.5年后,一些jr程序员会卷入半夜的风暴,因为网站突然被破坏了,即使它曾经工作过。追踪异常发生的位置是完全不可能的,因此,这个可怜的家伙将连续48小时在各地添加日志代码来追踪问题。他会发现某处的DBA决定将列MemberProjectId重命名为MemberProjectIdentifier,这导致linq崩溃

    想想孩子,处理例外,不要埋葬他们


    顺便说一句,是的,我就是那个必须找出这些类型错误的人。

    在编写代码之前,您似乎需要先阅读有关mvc3和实体框架的内容,并在这里寻求有关编码中充满错误做法的帮助

    回答您的问题:

    1-否

    2-作为1的答案毫无意义

    正确操作,以下是一些有用的文档:

    编辑:添加一些显式修复

    您可以从静态类访问dbcontext,如下所示:

    var context = DbProvider.CurrentDb;
    
    public static classDbProvider {
    
        public static void Initialize(){
            HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
            HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
        }
    
        private static void CreateDb(object sender, EventArgs e) {
            HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
        }
    
        private static void DisposeDb(object sender, EventArgs e)
        {
            Current.Dispose();
            HttpContext.Items.Remove("CurrentDb");
        }
    
        public static PbaDbEntities CurrentDb{
            get {
                return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
            }
        }
    }
    
    其思想是始终从这里访问数据库:从扩展方法和控制器操作

    然后,DbProvider.CurrentDb的实现如下:

    var context = DbProvider.CurrentDb;
    
    public static classDbProvider {
    
        public static void Initialize(){
            HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
            HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
        }
    
        private static void CreateDb(object sender, EventArgs e) {
            HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
        }
    
        private static void DisposeDb(object sender, EventArgs e)
        {
            Current.Dispose();
            HttpContext.Items.Remove("CurrentDb");
        }
    
        public static PbaDbEntities CurrentDb{
            get {
                return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
            }
        }
    }
    
    如您所见,它将为每个请求创建一个新的Db,并且仅在该请求中可用。这样,您的数据库将在每个请求结束时被处理。此模式在视图中称为“打开会话”

    最后,您需要初始化调用该方法的
    DbProvider
    Initialize()
    在您的Global.asax文件中,在事件应用程序启动时


    希望能有所帮助。

    在编写代码之前,您似乎需要先阅读有关mvc3和实体框架的内容,并在这里寻求有关编写了大量错误实践的帮助

    回答您的问题:

    1-否

    2-作为1的答案毫无意义

    正确操作,以下是一些有用的文档:

    编辑:添加一些显式修复

    您可以从静态类访问dbcontext,如下所示:

    var context = DbProvider.CurrentDb;
    
    public static classDbProvider {
    
        public static void Initialize(){
            HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
            HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
        }
    
        private static void CreateDb(object sender, EventArgs e) {
            HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
        }
    
        private static void DisposeDb(object sender, EventArgs e)
        {
            Current.Dispose();
            HttpContext.Items.Remove("CurrentDb");
        }
    
        public static PbaDbEntities CurrentDb{
            get {
                return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
            }
        }
    }
    
    其思想是始终从这里访问数据库:从扩展方法和控制器操作

    然后,DbProvider.CurrentDb的实现如下:

    var context = DbProvider.CurrentDb;
    
    public static classDbProvider {
    
        public static void Initialize(){
            HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
            HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
        }
    
        private static void CreateDb(object sender, EventArgs e) {
            HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
        }
    
        private static void DisposeDb(object sender, EventArgs e)
        {
            Current.Dispose();
            HttpContext.Items.Remove("CurrentDb");
        }
    
        public static PbaDbEntities CurrentDb{
            get {
                return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
            }
        }
    }
    
    如您所见,它将为每个请求创建一个新的Db,并且仅在该请求中可用。这样,您的数据库将在每个请求结束时被处理。此模式在视图中称为“打开会话”

    最后,您需要初始化调用该方法的
    DbProvider
    Initialize()
    在您的Global.asax文件中,在事件应用程序启动时


    希望它能有所帮助。

    我对这里的上下文没有任何概念——如果db只是一个类似于对象的连接,或者不是,但是看起来您正在丢弃并重新创建任何不必要的东西

    最好创建一个属性(无论你做什么),以便保持一致

    private static Thing _thing;
    private static Thing thing{
      get{
        if(_thing==null){
          _thing=new Thing();
        }
        return _thing;
      }
    }
    

    我不知道这里的上下文——如果db只是一个连接,比如