C#(MVC3)中静态(扩展)类中动态属性的行为是什么

本文关键字:是什么 属性 扩展 MVC3 静态 动态 | 更新日期: 2023-09-27 18:22:01

我是.NET和C#开发的新手,但我是一名长期的开发人员,使用C、C++、Java、PHP等。

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

我的问题是:

  1. 静态db变量可能会有这种行为,我说得对吗
  2. 是否有必要处理静态类中的动态变量,或者垃圾回收仍会自动处理它

以下是该类的相关片段:

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

C#(MVC3)中静态(扩展)类中动态属性的行为是什么

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

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

这样忽略异常是个糟糕的主意,如果你不想处理异常,就不要尝试/catch或catch&重新思考。这样想吧,在你埋葬了异常之后,你的程序处于无效状态,b/c是你无法控制的错误。现在,b/c您已经埋葬了异常,您的程序可以继续运行,但它的状态不好。

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

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

顺便说一句,是的,我一直是那种必须找出这些错误的人。

在编写代码之前,您似乎需要阅读有关mvc3和实体框架的内容,并在这里寻求有关充满不良实践的代码的帮助。

回答您的问题:

1-无

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

做对了,这里有一些有用的文档:http://msdn.microsoft.com/en-us/library/ie/gg416514(v=vs.98).aspx

编辑:添加一些显式修复

您可以从一个静态类访问您的dbcontext,类似于以下内容:

var context = DbProvider.CurrentDb;

这个想法是始终从这里访问数据库:从扩展方法和控制器操作。

然后,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事件Application_start中的Global.asax文件中的Initialize()

希望能有所帮助。

我对这里的上下文一无所知——如果db只是一个类似连接的对象,但它似乎是在丢弃和重新创建不必要的东西。

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

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