3

ObjectContextインスタンスはInRequestScopeに破棄されました!

私は問題を解決するためにウェブ上で数時間試しました。

ObjectContextインスタンスは破棄され、接続を必要とする操作には使用できなくなりました。

このこれこれこれのような同じ問題を持ついくつかの記事や投稿を見つけました

いろいろ試してみましたが、いつもエラーが発生します。


コード

コンテクスト

public class BindSolutionContext : DbContext
{
    public DbSet<Project> Projects { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Address> Addresses { get; set; }
    public DbSet<ProjectImage> ProjectImages { get; set; }

    public BindSolutionContext()
        : base("name=Data")
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BindSolutionContext>());
    }
}

注入する

kernel.Bind<BindSolutionContext>().ToSelf().InRequestScope();

kernel.Bind<IProjectRepository>().To<ProjectRepository>().InRequestScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope();
kernel.Bind<IRoleRepository>().To<RoleRepository>().InRequestScope();
kernel.Bind<IAddressRepository>().To<AddressRepository>().InRequestScope();
kernel.Bind<IProjectImageRepository>().To<ProjectImageRepository>().InRequestScope();

リポジトリ

public class ProjectRepository : IProjectRepository
{
    private readonly BindSolutionContext _context;

    public ProjectRepository(BindSolutionContext context)
    {
        _context = context;
    }

    public IQueryable<Project> Query(params Expression<Func<Project, object>>[] includeProperties)
    {
        return includeProperties.Aggregate<Expression<Func<Project, object>>,
            IQueryable<Project>>(_context.Projects, (current, includeProperty) => current.Include(includeProperty));
    }

    public IQueryable<Project> Query(int pageIndex, int pageSize, params Expression<Func<Project, object>>[] includeProperties)
    {
        return includeProperties.Aggregate<Expression<Func<Project, object>>,
            IQueryable<Project>>(_context.Projects, (current, includeProperty) => current.Include(includeProperty)).OrderBy(p => p.Name).Skip(pageIndex).Take(pageSize);
    }

    //Rest of Implementation
}

、、のProjectImageRepository場合AddressRepository、実装は同じモデルに従います。RoleRepositoryUserRepository

public class BindUserProvider : MembershipProvider
{
    [Inject]
    public IUserService UserService { get; set; }

    //Rest of implementation
}


public class BindRoleProvider : RoleProvider
{
    private IRoleService _roleServ;
    private IRoleService RoleServ { get { return _roleServ ?? (_roleServ = DependencyResolver.Current.GetService<IRoleService>()); } }

    private IUserService _userServ;
    private IUserService UserServ { get { return _userServ ?? (_userServ = DependencyResolver.Current.GetService<IUserService>()); } }

    //Rest of implementation
}

スコープはリクエストであるため、Ninjectはリクエストの最後にオブジェクトを破棄する必要があります。ただし、状況によっては、リクエストを確定する前に破棄が発生します。

試み

問題がカスタムメンバーシップに関連しているかどうかはわかりませんが、いくつかのテストを行いました。次のとおりです。

注入する

kernel.Bind<BindSolutionContext>().ToSelf().InTransientScope();

kernel.Bind<IProjectRepository>().To<ProjectRepository>().InSingletonScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InSingletonScope();
kernel.Bind<IRoleRepository>().To<RoleRepository>().InSingletonScope();
kernel.Bind<IAddressRepository>().To<AddressRepository>().InSingletonScope();
kernel.Bind<IProjectImageRepository>().To<ProjectImageRepository>().InSingletonScope();

したがって、これ以上のエラーはありません!

しかし、別の問題が発生します!repositoryおよびcontextはシングルトンオブジェクトであるため、更新されません。

たとえば、プロジェクトに新しいアドレスを登録しても、コレクションproject.Addressesは更新されません。

注:アドレスは問題なくデータベースに登録されています!

4

3 に答える 3

5

メンバーシップとRoleProviderは、リクエストよりもライフサイクルが長くなります。オブジェクトは、破棄されたオブジェクトを参照することになるため、(メソッドの実行中にローカルで作成および破棄されない限り)存続期間の短いオブジェクトに依存しないようにする必要があります。

オブジェクトがキャッシュされないようにリクエストごとに新しいコンテキストが必要なため、コンテキストをリポジトリに挿入するのではなく、メソッド呼び出しを使用して外部から渡し、ファクトリを使用してサービスまたはプロバイダーで作成する必要があります。

于 2011-12-10T23:20:21.797 に答える
1

この例外を回避するには、ライフサイクルが長いクラス(アクションフィルター、メンバーシッププロバイダーなど)に挿入されたプロパティの代わりにDependencyResolver.Current.GetService()を使用します。このアプローチはテストに適していませんが、InRequestScope()を使用すると、現在のhttp-requestのデータコンテキストインスタンスにアクセスできます。

于 2012-05-16T09:20:31.077 に答える
0

依存性注入を削除し、このようにしました...

    public class CustomRoleProvider:RoleProvider
    {
        private IGroupService _groupService;
        private MyDbContext context;

         public CustomRoleProvider()
         {
              //  _groupService = DependencyResolver.Current.GetService<IGroupService>();
              context = new MyDbContext();
             _groupService = new GroupService(new GroupRepository(context), new AccountRepository(context));

         }

    }
于 2012-08-25T12:38:54.793 に答える