在EF 4.0中,Is static类获取dbcontext是一个很好的方法
本文关键字:一个 方法 很好 dbcontext 获取 EF static Is | 更新日期: 2023-09-27 18:24:25
我想知道创建一个静态类来获取实体数据库上下文是否是一种好的做法。
此GetEntity()
返回上下文。在GetEntity
方法中,我有一个动态连接。当有人进入我的登录页面时,他们需要提供数据库号码+用户名+密码。我把数据库名存放在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上下文。
- 我这样做正确吗
- 如果20个客户端同时登录,但使用不同的dbname,这可能是一个问题
- 目前,我没有使用任何处置,这有问题吗?基于我的
EntityFactory
类,我可以在该类中制作一个全局可丢弃的,它将被自动调用吗。(我想到了descrutor方法)
static
工厂方法可能很难模拟单元测试。例如,在你的控制器中,如果你有:
public void SomeControllerMethod()
{
var entities = EntityFactory.GetEntity();
return entities.Something // ... get whatever data...
}
那么,您将如何在单元测试中使用模拟数据上下文呢?这将很难做到。最好将上下文"注入"到控制器中,通常是通过构造函数(如果你不熟悉这个概念,请阅读维基百科上关于"依赖反转主体"的文章),比如:
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>
模拟大部分数据层,而不是实际的数据库,你可以将记录"加载"answers"保存"到内存中的列表中,并且永远不会接触实际的数据库。
按顺序:
-
您可以通过将所需的所有信息(如数据库名、用户名和密码)传递给
GetEntity()
来改进它。现在,静态方法与会话紧密耦合。将会话从方法中移出。 -
它不应该是每个用户的会话。
-
如果
DBEntities
继承自DbContext
,则可以在使用对象后调用Dispose。Es:dbEntitiesObj.Dispose();