Linq的DataContexts和“工作单元”模式。我的方法好吗?

时间:2011-12-23 11:34:40

标签: linq-to-sql design-patterns datacontext webforms unit-of-work

按照许多文章的说明,我决定在我的Unit of work中将Linq2SQL DataContexts模式实施到我的ASP.Net WebForms Application,但我不确定我是否在正确的方式。

这是我到目前为止所做的事情:

1 - 在每个Request上,我在Application_AcquireRequestState中捕获Global.asax事件(可以访问会话数据)并实例化一个新的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 - 每个Data Access Layer对象(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存储在用户的会话中是否可以?什么是另一种选择? 我的应用程序有很多PageMethods调用,所以我担心DTX在异步请求存储在会话中时会失效。
  2. 我是否需要将Application_ReleaseRequestState事件捕获到Dispose()的{​​{1}}并将其从会话中删除?
  3. 如果我不需要在每个DataContext中处理它,那么Application_AcquireRequestStateRemove DTX from Session - Create DTX - Store it会更好吗?
  4. 另外,如果我不需要处理它,那么Refresh呢?它会自动处理它们还是我也需要控制它们?
  5. 感谢您的时间和帮助:)

    - 编辑

    根据@ ivowiblo的建议,这是我达到的代码:

    Global.asax中

    Connections

    GenericDAO

    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();
            }
        }
    }
    

    这很简单!

2 个答案:

答案 0 :(得分:1)

您说您正在实施工作单元,但通过将其存储在缓存中,您并不真正坚持使用该工作单元。

我的建议是为每个请求创建一个新的DataContext,而不是将其任意缓存。

答案 1 :(得分:1)

最好的方法是将其放在HttpContext.Current.Items上,在RequestBegin上创建DataContext并将其置于RequestEnd中。在msdn中有一篇有趣的文章,关于更好地管理DataContext,建议使用短时间的DataContext实例。

此模式称为Open session in view,是为在Web环境中使用NHibernate而创建的。