【问题标题】:In EF 4.0, Is static class to get the dbcontext is a good way to go?在 EF 4.0 中,获取 dbcontext 的静态类是一个好方法吗?
【发布时间】:2012-03-06 00:08:04
【问题描述】:

我想知道创建一个静态类来获取实体数据库上下文是否是一个好习惯。

ThisGetEntity() 返回上下文。在GetEntity 方法中,我有一个动态连接。 当有人访问我的登录页面时,他们需要提供一个数据库号 + 用户名 + 密码。我将 dbname 存入 Session["DBName"]

public static class EntityFactory
    {
        public static DBEntities GetEntity()
        {
            var scsb = new SqlConnectionStringBuilder();

            scsb.DataSource = ConfigurationManager.AppSettings["DataSource"];

            scsb.InitialCatalog = "db1";
            scsb.MultipleActiveResultSets = true;
            scsb.IntegratedSecurity = true;
            if (HttpContext.Current.Session["DBName"] == null)
            {
                HttpContext.Current.Response.Redirect("/Account/Step1");
            }
            else 
            {
                scsb.InitialCatalog = HttpContext.Current.Session["DBName"].ToString(); 
            }

            var builder = new EntityConnectionStringBuilder();

            builder.Metadata = "res://*/nms.bin.Models.DBModel.csdl|res://*/nms.bin.Models.DBModel.ssdl|res://*/nms.bin.Models.DBModel.msl";
            builder.Provider = "System.Data.SqlClient";
            builder.ProviderConnectionString = scsb.ConnectionString;
            DBEntities db = new DBEntities(builder.ConnectionString);
            return db;
        }

当我想在控制器中通过示例获取 DBContext 时,我只需要执行 EntityFactory.GetEntity() 并返回一个 DB 上下文。

  1. 我这样做的方式是否正确
  2. 如果 20 个客户端同时登录但使用不同的 dbname,这可能是个问题。
  3. 目前,我没有使用任何 dispose,有问题吗?根据我的EntityFactory 课程,我可以在该课程中制作一个将自动调用的全局一次性用品。 (我想到了 descutor 方法)。

【问题讨论】:

  • @Eranga 非常感谢您的编辑,我的英语不好:)

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


【解决方案1】:

static 工厂方法可能难以模拟以进行单元测试。因此,如果您有以下情况,例如在您的控制器中:

public void SomeControllerMethod()
{
    var entities = EntityFactory.GetEntity();
    return entities.Something // ... get whatever data...
}

那么您将如何在单元测试中使用模拟数据上下文?这将很难做到。 最好将上下文“注入”到控制器中,通常是通过构造函数(如果您不熟悉该概念,请阅读关于“dependency inversion principal”的维基百科文章),例如:

public class SomeController
{
    private readonly IDBEntities entities;

    // db context passed in through constructor,
    // to decouple the controller from the backing implementation.
    public void SomeController(IDBEntities entities)
    {
        this.entities = entities;
    }
}

然后让控制器方法使用传入的引用。这样你就可以使用依赖注入工具来获取合适的数据库上下文,或者传入一个模拟上下文。

我不确定 MVC2 是否有添加依赖注入框架的好方法,但我知道 MVC3 可以。

你的方法也行得通,它根本没有什么问题,只是似乎更难测试。当然,如果您不进行任何单元测试并且不需要使用模拟数据存储,那么我想这真的没关系:)

我通常最终使用带有 EntityFramework Code-First 的 MVC3,结果非常好,并且您可以使用 List<T> 而不是实际的数据库来模拟大部分数据层,您可以“加载”和“保存”记录到内存列表,永远不要接触真正的数据库。

【讨论】:

    【解决方案2】:

    按顺序:

    1. 您可以通过将它需要的所有信息(如数据库名、用户名和密码)传递给GetEntity() 来改进它。就像现在一样,静态方法与会话紧密耦合。将会话从方法中移出。

    2. 它不应该是每个用户的会话。

    3. 如果 DBEntities 继承自 DbContext 您可以在使用对象后调用 Dispose。西:dbEntitiesObj.Dispose();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      相关资源
      最近更新 更多