Linq 的 DataContext 和“工作单元”图案。我的做法可以吗?
按照许多文章的指示,我决定在 ASP.Net WebForms 应用程序
中对 Linq2SQL DataContexts
实现工作单元
模式,但我不确定我是否走在正确的道路上。
这是我到目前为止所完成的工作:
1 - 在每个 Request
上,我捕获 Global.asax< 中的
Application_AcquireRequestState
事件(可以访问会话数据) /code> 并实例化一个新的 DataContext
以将其绑定到用户的 Session
:
void Application_AcquireRequestState(object sender, EventArgs e)
{
// Check if the request is for a Page, Page Method or Handler
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
MyCompany.MyDatabaseDataContext myDatabaseDataContext = new MyCompany.MyDatabaseDataContext();
HttpContext.Current.Session["myDatabaseDataContext"] = myDatabaseDataContext;
}
}
2 - 每个 数据访问层
对象 (DAO) 都继承自根据DAO
: GenericDAO
:
public class GenericDAO
{
private MyDatabaseDataContext _dbMyDatabase;
protected MyDatabaseDataContext dbMyDatabase
{
get
{
if (_dbMyDatabase == null)
_dbMyDatabase = HttpContext.Current.Session["myDatabaseDataContext"] as MyDatabaseDataContext;
return _dbMyDatabase;
}
}
}
3 - 因此,在每个操作中,DAO
使用其父类的 DataContext
属性:
public class MyTableDAO : GenericDAO
{
public List<MyTable> getAll()
{
return dbMyDatabase.GetTable<MyTable>().ToList();
}
}
这是我的担忧...
- 首先,可以将
DataContext
存储在用户的 Session 中吗?另一种选择是什么? 我的应用有很多 PageMethods 调用,因此我担心如果 DTX 存储在会话中,它们的异步请求之间会失效。 - 我是否需要捕获
DataContext
的Dispose()
的Application_ReleaseRequestState
事件并将其从会话中删除? - 如果我不需要在每个
Application_AcquireRequestState
中处理它,最好是从会话中删除 DTX - 创建 DTX - 存储它
还是只是刷新
吗? - 另外,如果我不需要处理它,那么
Connections
呢?它会自动处理它们还是我也需要控制它们?
我感谢您的时间和帮助:)
-- 编辑
这是我根据@ivowiblo的建议达到的代码:
Global.asax
void Application_BeginRequest(object sender, EventArgs e)
{
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
MyCompany.MyDatabaseDataContext myDatabaseDataContext = new MyCompany.MyDatabaseDataContext();
HttpContext.Current.Items["myDatabaseDataContext"] = ceabsDataContext;
}
}
void Application_EndRequest(object sender, EventArgs e)
{
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
if (HttpContext.Current.Items["myDatabaseDataContext"] != null)
{
System.Data.Linq.DataContext myDbDtx = HttpContext.Current.Items["myDatabaseDataContext"] as System.Data.Linq.DataContext;
if (myDbDtx != null)
myDbDtx.Dispose();
}
}
}
GenericDAO
public class GenericDAO
{
protected MyDatabaseDataContext dbMyDatabase
{
get
{
return HttpContext.Current.Items["myDatabaseDataContext"] as MyDatabaseDataContext;
}
}
}
就这么简单!
Following the directions from many articles, I've decided to implement the Unit of work
pattern to my Linq2SQL DataContexts
in my ASP.Net WebForms Application
, but I'm not sure if I'm on the right way.
Here's what I'm accomplishing so far:
1 - On every Request
, I catch the Application_AcquireRequestState
event (which has access to Session data) in Global.asax
and instantiate a new DataContext
to bind it to the user's Session
:
void Application_AcquireRequestState(object sender, EventArgs e)
{
// Check if the request is for a Page, Page Method or Handler
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
MyCompany.MyDatabaseDataContext myDatabaseDataContext = new MyCompany.MyDatabaseDataContext();
HttpContext.Current.Session["myDatabaseDataContext"] = myDatabaseDataContext;
}
}
2 - Every Data Access Layer
Object (DAO) inherits from a base DAO
: GenericDAO
:
public class GenericDAO
{
private MyDatabaseDataContext _dbMyDatabase;
protected MyDatabaseDataContext dbMyDatabase
{
get
{
if (_dbMyDatabase == null)
_dbMyDatabase = HttpContext.Current.Session["myDatabaseDataContext"] as MyDatabaseDataContext;
return _dbMyDatabase;
}
}
}
3 - So, in every operation, the DAO
use the DataContext
Property from its parent class:
public class MyTableDAO : GenericDAO
{
public List<MyTable> getAll()
{
return dbMyDatabase.GetTable<MyTable>().ToList();
}
}
Here's my concerns...
- First of all, is it ok to store the
DataContext
in the user's Session? What would be another option? My app has a lot of PageMethods calls, so I'm worried the DTX would be invalidated between their async requests if it is stored in the session. - Do I need to capture the
Application_ReleaseRequestState
event toDispose()
of theDataContext
and remove it from the session? - If I don't need to Dispose of it, in every
Application_AcquireRequestState
, would it be better toRemove DTX from Session - Create DTX - Store it
or justRefresh
it? - Also, if I don't need to Dispose of it, what about
Connections
? Would it handle them automatically or I would need to control them too?
I appreciate your time and help :)
-- EDIT
Here's the code I've reached, following @ivowiblo's suggestion:
Global.asax
void Application_BeginRequest(object sender, EventArgs e)
{
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
MyCompany.MyDatabaseDataContext myDatabaseDataContext = new MyCompany.MyDatabaseDataContext();
HttpContext.Current.Items["myDatabaseDataContext"] = ceabsDataContext;
}
}
void Application_EndRequest(object sender, EventArgs e)
{
if (new Regex(@"\.(aspx|ashx)(/.*)?$").IsMatch(HttpContext.Current.Request.Url.AbsolutePath))
{
if (HttpContext.Current.Items["myDatabaseDataContext"] != null)
{
System.Data.Linq.DataContext myDbDtx = HttpContext.Current.Items["myDatabaseDataContext"] as System.Data.Linq.DataContext;
if (myDbDtx != null)
myDbDtx.Dispose();
}
}
}
GenericDAO
public class GenericDAO
{
protected MyDatabaseDataContext dbMyDatabase
{
get
{
return HttpContext.Current.Items["myDatabaseDataContext"] as MyDatabaseDataContext;
}
}
}
Simple as that!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最好的方法是将其放在
HttpContext.Current.Items
上,在RequestBegin
上创建 DataContext 并将其处置在RequestEnd
中。在 msdn 有一篇关于更好地管理 DataContext 的有趣文章,其中建议使用短时 DataContext 实例。此模式称为
在视图中打开会话
,是为在 Web 环境中使用 NHibernate 而创建的。The best approach is to put it on
HttpContext.Current.Items
, creating the DataContext onRequestBegin
and dispose it inRequestEnd
. In msdn there's an interesting article about the better management of the DataContext, where it's suggested to have short-time DataContext instances.This pattern is called
Open session in view
and was created for using NHibernate in web environments.您说您正在实现工作单元,但是通过将其存储在缓存中,您并没有真正坚持该工作单元。
我的建议是为每个请求创建一个新的DataContext,而不是缓存它。
You say you are implementing unit-of-work, but by storing it in the cache you do not really stick to that unit-of-work.
My advice is to create a new DataContext for every request and not to cache it anyware.