DataContexts Linq и шаблон «Единица работы». Мой подход в порядке? - PullRequest
2 голосов
/ 23 декабря 2011

Следуя указаниям многих статей, я решил применить шаблон 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() DataContext и удаление его из сеанса?
  3. Если мне не нужно утилизировать его, в каждом Application_AcquireRequestState было бы лучше Remove DTX from Session - Create DTX - Store itили просто Refresh это?
  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;
        }
    }
}

Простойкак то!

Ответы [ 2 ]

1 голос
/ 24 декабря 2011

Лучший подход - поместить его на HttpContext.Current.Items, создать DataContext на RequestBegin и расположить в RequestEnd msdn есть интересная статья о лучшем управлении DataContext, где предлагается иметь кратковременные экземпляры DataContext.

Этот шаблон называется Open session in view и был создан для использования NHibernateв веб-среде.

1 голос
/ 23 декабря 2011

Вы говорите, что реализуете единицу работы, но, сохраняя ее в кеше, вы на самом деле не придерживаетесь этой единицы работы.

Мой совет - создать новый DataContext для каждый запрос и не кэшировать его.

...