Каков наилучший способ создания экземпляра EF DbContext для ASP.NET MVC - PullRequest
1 голос
/ 19 марта 2012

Для поддержки функции отложенной загрузки в EF, как лучше всего создать экземпляр DbContext?

Я знаю, что текущий элемент HttpContext является хорошим местом для создания DbContext через * 1006.* method и Application_EndRequest method, но в некоторых примерах кодов MSDN и официального сайта mvc asp.net они просто создают DbContext в конструкторе контроллера и располагают его в методе Dispose() контроллера.

Я думаюоба пути не слишком различаются, потому что все они реализуют сеанс для каждого шаблона запроса.

Я просто хочу убедиться, что мое понимание верно или нет.

Ответы [ 3 ]

1 голос
/ 19 марта 2012

Любая отложенная загрузка может потенциально стать ловушкой для будущего выпуска. Без DI, без репозитория - трудно увидеть что-либо работающее без хака ленивой загрузки. Кроме того, вы планируете передать ваши лица на ваш взгляд. Если так, то это создаст плохое перекрытие. Контроллер должен упаковать данные для вашего представления, а не оценивать вещи позже в вашем представлении.

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

1 голос
/ 19 марта 2012

Метод Dispose() в контроллере не всегда надежен.К тому же, сессия, вероятно, тоже не очень хорошая идея.«Лучшее», вероятно, субъективно, но мы добились наилучшего успеха, используя внедрение зависимостей (Castle Windsor) и следуя шаблону хранилища единиц работы.

Установите единицы работы следующим образом:

public class UnitOfWork : IUnitOfWork
{
    public UnitOfWork()
    {
        this.Context = new MyEFEntities();
        this.Context.ContextOptions.LazyLoadingEnabled = true;
    }

    public void Dispose()
    {
        this.Context.Dispose();
    }

    public ObjectContext Context { get; internal set; }
}

Настройте свой репозиторий:

public class Repository<TEntity> : IRepository<TEntity>
    where TEntity : class
{
    public Repository(IUnitOfWork unitOfWork)
    {
        Context = unitOfWork.Context;
        ObjectSet = Context.CreateObjectSet<TEntity>();
    }
    public ObjectContext Context { get; set; }
    public IObjectSet<TEntity> ObjectSet { get; set; }
}

Зарегистрируйтесь в Castle в Global.asax:

void Application_Start()
{
    this.Container.Register(
        Component.For<IUnitOfWork>()
            .UsingFactoryMethod(() => new UnitOfWork())
            .LifeStyle
            .Is(LifestyleType.PerWebRequest)
        );

    ControllerBuilder.Current.SetControllerFactory(
        new WindsorControllerFactory(this.Container));
}

И использовать в вашем контроллере (или везде, где вы его используете, пока он вводится):

public class SomeController
{
    public SomeController(IRepository<MyEntity> repository)
    {
        this.Repository = repository;
    }

    public IRepository<MyEntity> Repository { get; set; }

    public ActionResult MyAction()
    {
        ViewData.Model = this.Repository.ObjectSet.Single(x => x.Condition); //or something...
    }
}
0 голосов
/ 19 января 2013

Я использовал шаблон фабрики сеансов и сохранил DBContext в объекте сеанса.Он останется открытым для каждой сессии.У меня до сих пор с этим не было проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...