Re[5]: Linq with BLToolkit
От: Erty Hackward Россия http://april32.com
Дата: 05.08.10 16:10
Оценка:
Здравствуйте, 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 запросов в сек (независимо от схемы).

Насколько вторая схема правильная?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.