c# - 在 EF 4.0 中,获取 dbcontext 的静态类是否是一种好方法?

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

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

GetEntity() 返回上下文。在 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;
        }

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

  1. 我这样做的方式是否正确
  2. 如果 20 个客户端同时登录但使用不同的 dbname,这会不会是一个问题。
  3. 目前,我没有使用任何 dispose,有问题吗?基于我的 EntityFactory 类,我可以在该类中创建一个全局一次性对象,它将被自动调用。 (我想到了 descrutor 方法)。

最佳答案

static工厂方法很难模拟单元测试。那么在你的 Controller 中的例子如果你有:

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

那么您将如何在单元测试中使用模拟数据上下文?这很难做到。 最好将上下文“注入(inject)”到 Controller 中,通常是通过构造函数(如果您不熟悉这个概念,请阅读关于“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;
    }
}

然后让 Controller 方法使用传入的引用。通过这种方式,您可以使用依赖项注入(inject)工具来获取适当的数据库上下文,或传入模拟上下文。

虽然我不确定 MVC2 是否有添加依赖项注入(inject)框架的好方法,但我知道 MVC3 有。

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

我通常最终将 MVC3 与 EntityFramework Code-First 结合使用,结果非常好,您可以使用 List<T> 模拟大部分数据层。您可以将记录“加载”和“保存”到内存列表,而不是实际的数据库,而不是实际的数据库。

关于c# - 在 EF 4.0 中,获取 dbcontext 的静态类是否是一种好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9280015/

相关文章:

asp.net-mvc-3 - 更新标记实体日期时间属性不变时

asp.net-mvc - EF 4 代码如何首先处理生产环境中的架构更改?

c# - 在 Windows Phone 8 中异步下载和保存文件

c# - WPF:按下回车按钮时在搜索字段中执行命令绑定(bind)

c# - 没有访问服务器配置的 asp.net mvc 2 的 GZip 或 Deflate 压缩

asp.net-mvc-2 - Html.Hidden() 插入错误值

entity-framework-4 - 使用外键引用创建新的 EF 对象而不加载整个重新引用对象

c# - 在 codedom 中使用动态对象创建 LINQ 查询

c# - 在 asp.net 上的 sql server 中插入空值,并提供必填字段验证器

c# - .Net MVC 中带有 AJAX 的嵌套表单