Здравствуйте, IT, Вы писали:
IT>В принципе, на сегодняшний день, DataContext является интерфейсом и полностью отчуждаем. При желании можно написать DataContext на свой вкус и цвет.
Наверное, я не правильно выразился. Наш DataContext напрямую наследуется от DbManager и в нем просто реализуются свойства, которые вызывают DbManager.GetTable<T>.
Мы реализовали схему, при которой не требуется явное освобождение ресурсов.
Базовый репозиторий:
public class Repository<T> where T : DbManager, new()
{
public T Context {
get { return DataContext.Value; }
}
[ThreadStatic]
private volatile static Lazy<T> dataContext;
public static Lazy<T> DataContext {
get { return dataContext ?? (dataContext = new Lazy<T>( () => new T())); }
set { dataContext = value; }
}
}
Реализация репозитория: (OlympDataContext — наш domain класс, который генерируется dblinq из БД, наследует DbManager)
public class NewsRepository : Repository<OlympDataContext>
{
public List<News> GetAllNews()
{
return Context.News.ToList();
}
}
Освобождение DbManager происходит в Global.asax.cs
protected void Application_EndRequest(object sender, EventArgs e)
{
var lazy = Repository<OlympDataContext>.DataContext;
if (lazy.IsValueCreated)
{
lazy.Value.Dispose();
Repository<OlympDataContext>.DataContext = null;
}
}
Таким образом мы имеем один DbManager на все запросы для каждой страницы. Можно создавать любое количество репозиториев в контроллерах. Не нужно беспокоиться о освобождении ресурсов.
Эта схема работает. Имеем ~250 страниц в секунду на средней клиентской машине при 5 запросах к mysql.
Это вторая реализация. Первая инициализировалась следующим образом:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var lazy = new Lazy<OlympDataContext>(() => new OlympDataContext());
Repository<OlympDataContext>.DataContext = lazy;
}
Схема работала до того момента как мы начали использовать in-proc сессию. Как только мы добавили кэширование в сессии, начались случайные выпады в DbManager NullReferenceException при обращении к DbManager._connection. Стоит заметить, что из-за использования сессии производительность падает до 120 запросов в сек (независимо от схемы).
Насколько вторая схема правильная?