Linq 的 DataContext 和“工作单元”图案。我的做法可以吗?

发布于 2024-12-22 18:21:10 字数 3316 浏览 2 评论 0原文

按照许多文章的指示,我决定在 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();
    }
}

这是我的担忧...

  1. 首先,可以将 DataContext 存储在用户的 Session 中吗?另一种选择是什么? 我的应用有很多 PageMethods 调用,因此我担心如果 DTX 存储在会话中,它们的异步请求之间会失效。
  2. 我是否需要捕获 DataContextDispose()Application_ReleaseRequestState 事件并将其从会话中删除?
  3. 如果我不需要在每个 Application_AcquireRequestState 中处理它,最好是从会话中删除 DTX - 创建 DTX - 存储它 还是只是刷新 吗?
  4. 另外,如果我不需要处理它,那么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...

  1. 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.
  2. Do I need to capture the Application_ReleaseRequestState event to Dispose() of the DataContext and remove it from the session?
  3. If I don't need to Dispose of it, in every Application_AcquireRequestState, would it be better to Remove DTX from Session - Create DTX - Store it or just Refresh it?
  4. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤芳又自赏 2024-12-29 18:21:10

最好的方法是将其放在 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 on RequestBegin and dispose it in RequestEnd. 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.

紫南 2024-12-29 18:21:10

您说您正在实现工作单元,但是通过将其存储在缓存中,您并没有真正坚持该工作单元。

我的建议是为每个请求创建一个新的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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文