Множественные Telerik MVC-сетки в TabStrip не работают с инфраструктурой объектов и объектов, единицей работы, шаблоном хранилища - PullRequest
1 голос
/ 03 марта 2012

Я создаю веб-сайт электронной коммерции ASP.NET MVC 3, и в настоящее время я работаю в области администратора, где вы можете добавлять / редактировать продукты. Для создания пользовательского интерфейса для страницы продукта я использую элементы управления Telerik MVC.

Моя проблема заключается в том, что, когда я добавил вторую сетку Telerik, которая одновременно извлекает данные из базы данных посредством вызова ajax, я получаю несколько разных ошибок, перечисленных ниже:

{"Уже есть открытый DataReader, связанный с этой командой который должен быть закрыт первым. "}

{"Соединение не было закрыто. Текущее состояние соединения подключения. "}

Код контекста базы данных

public interface IUnitOfWork
{
    void Commit();
}

public class GSPDataContext : DbContext, IUnitOfWork
{
    /* (omitted) IDbSet's for entities */
    public GSPDataContext()
      : base("GSPConnectionString")
    {

    }

    public virtual IDbSet<T> DbSet<T>() where T : class
    {
       return Set<T>();
    }

    public virtual void Commit()
    {
        base.SaveChanges();
    }
}

Общий код репозитория

public class Repository<T> : IRepository<T> where T : class
{
    private GSPDataContext m_dataContext;
    private readonly IDbSet<T> m_entity;

    public Repository(GSPDataContext dataContext)
    {
        if (dataContext == null)
            throw new ArgumentException();

        m_dataContext = dataContext;

        m_entity = m_dataContext.Set<T>();
    }

    public T GetById(int id)
    {
        return this.m_entity.Find(id);
    }

    public void Insert(T entity)
    {
        if (entity == null)
            throw new ArgumentException();

        this.m_entity.Add(entity);

        //this.m_dataContext.SaveChanges();
    }

    public void Delete(T entity)
    {
        if (entity == null)
            throw new ArgumentException();

        this.m_entity.Remove(entity);

        //this.m_dataContext.SaveChanges();
    }

    public virtual IQueryable<T> Table
    {
        get
        {
            return this.m_entity;
        }
    }
}

Код Ninject

private static void RegisterServices(IKernel kernel)
    {
        //Customer
        kernel.Bind<IAddressValidationService>().To<AddressValidationService>().InRequestScope();
        kernel.Bind<ICustomerService>().To<CustomerService>().InRequestScope();
        kernel.Bind<ICustomerProductService>().To<CustomerProductService>().InRequestScope();

        //Authentication
        kernel.Bind<IOpenIDLoginService>().To<OpenIDLoginService>().InRequestScope();
        kernel.Bind<IAuthenticationService>().To<FormsAuthenticationService>().InRequestScope();

        //Products
        kernel.Bind<IProductService>().To<ProductService>().InRequestScope();
        kernel.Bind<IRecentlyViewedProductService>().To<RecentlyViewedProductService>().InRequestScope();
        kernel.Bind<IProductPictureService>().To<ProductPictureService>().InRequestScope();
        kernel.Bind<ICategoryService>().To<CategoryService>().InRequestScope();
        kernel.Bind<IPictureService>().To<PictureService>().InRequestScope();

        //Shopping Cart
        kernel.Bind<IShoppingCartService>().To<ShoppingCartService>().InRequestScope();

        //Shipping and Payment
        kernel.Bind<IShippingService>().To<ShippingService>().InRequestScope();
        kernel.Bind<IPaymentService>().To<PaymentService>().InRequestScope();

        //Orders
        kernel.Bind<IOrderCalculationService>().To<OrderCalculationService>().InRequestScope();
        kernel.Bind<IOrderProcessingService>().To<OrderProcessingService>().InRequestScope();
        kernel.Bind<IOrderService>().To<OrderService>().InRequestScope();

        //
        kernel.Bind<IEncryptionService>().To<EncryptionService>().InRequestScope();
        kernel.Bind<ILogger>().To<LoggingService>().InRequestScope();
        kernel.Bind<IWebManager>().To<WebManager>().InRequestScope();

        //Messages
        kernel.Bind<IEmailService>().To<EmailService>().InRequestScope();
        kernel.Bind<IMessageTemplateService>().To<MessageTemplateService>().InRequestScope();
        kernel.Bind<IWorkflowMessageService>().To<WorkflowMessageService>().InRequestScope();

        //Data
        kernel.Bind<GSPDataContext>().ToSelf().InSingletonScope();
        kernel.Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<GSPDataContext>()).InSingletonScope();
        kernel.Bind(typeof (IRepository<>)).To(typeof (Repository<>)).InRequestScope();

        kernel.Bind<IWorkContext>().To<WebWorkContext>().InRequestScope();
    }

Я подозреваю, что это как-то связано с тем, как ninject управляет временем жизни различных сервисов, но я не уверен, что мне нужно сделать, чтобы это работало.

Любой совет будет высоко ценится.

Спасибо

UPDATE

Согласно комментарию Ремо, я изменяю свой код на следующий:

//Data
    kernel.Bind<GSPDataContext>().ToSelf().InRequestScope();
    kernel.Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<GSPDataContext>()).InRequestScope();
    kernel.Bind(typeof (IRepository<>)).To(typeof (Repository<>)).InRequestScope();

И теперь я получаю следующую ошибку:

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

Есть идеи?

1 Ответ

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

Нет, это не имеет ничего общего с тем, как Ninject управляет жизнями.Но он должен делать так, как вы настроили жизненные циклы.

Важно, чтобы новый DbContext использовался для каждого запроса.Это должен быть InRequestScope.

...