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