我想了解有关创建数据库实体(连接?)的更多信息。 来自PHP / MySQL,我只创建了一个连接,并且一遍又一遍地重复使用连接池。
我注意到在MVC中,我几乎每次都有机会创建新的db实体。在现实世界的例子中,这真的是正确的方法吗?
例如,我有一个代码告诉用户他们在每个刷新/页面视图中留下了多少未读消息。它是这样的:
public int UnreadMessages()
{
using (dbEntities db = new dbEntities())
{
return db.messages.Select(M => M.status == "Unread").Count();
}
}
在我的_Layout.html上,我有一行调用此代码。因此,这是在每个请求上执行的。我看待它的方式,这是一种可怕的方式,因为我不断创建一个新的连接?或者这可能是它应该在MVC上完成的方式。
有人可以向我解释,这样做的最好方法是什么?或者提供一些可以帮助我更好地理解这一点的链接?
P.S。我也不太确定MVC上的db连接是如何工作的。建立了一个连接,并在请求上创建了新的数据库实体(不是连接,而只是一个呼叫?),或者对请求建立了新的全新连接。
答案 0 :(得分:1)
在mvc世界中,视图(包括布局)应仅使用模型中的数据或包含使用RenderAction()的部分视图,以便从其他操作中获取模型。
你问关于连接和EF,虽然经常打开和处理对象不是很好,你需要了解EF有自己的连接池,所以如果你的动作调用一堆所有创建和处置自己的方法dbEntities()对象,将只使用与实际数据库的一个连接。
答案 1 :(得分:1)
两件事,Entity框架使用底层ADO.NET,它支持强大的连接池,并且通过上下文立即关闭与数据库的连接。所以你不必担心连接池。
但是,每次单个操作创建和销毁上下文并不是一个好主意。理想情况下,只应为请求的整个生命周期创建一个上下文。由于创建和销毁上下文的成本很低,因此会影响高负载下的性能。
Controller具有OnDispose方法,这就是您可以轻松实现它的方法,
public abstract class DBController : Controller {
public MyDbContext DbContext { get; private set; }
public DBController() {
DbContext = new ...
HttpContext.Items["DbContext"] = DbContext;
}
protected override void OnDispose() {
DbContext.Dispose();
}
}
您的每个Controller都应该来自DBController。在布局文件中,您可以通过检索HttpContext.Items["DbContext"]
这样,相同的上下文将用于整个请求。是的,对于每个请求,都将创建新的上下文。 EF不是设计为线程安全的,不应该为不同的请求重用。
答案 2 :(得分:0)
在我看来,建议使用using来创建新实例,因为它会在连接后自动关闭连接并处理实例。
如果你想使用一个全局变量,你需要确保在每个方法中打开和关闭数据库连接,然后它仍然没问题。
但是,您正在做的坏事是从_Layout.html调用数据库连接,即视图,应该只呈现视图;不要连接到DB。