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>());
}
}
Ninject
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
,RoleRepository
和UserRepository
实施遵循相同的模式!
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应该在请求结束时处理对象。但在某些情况下,在最终确定请求之前会发生处理。
我不确定问题是否与自定义成员身份有关,但是做了一些测试。如下:
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
不会更新!
注意:地址已在数据库中注册,没有任何问题!
答案 0 :(得分:5)
成员资格和角色提供者的生命周期比请求更长。对象永远不应该依赖于较短的对象(除非在方法执行期间本地创建和销毁),因为它们最终会引用已处置的对象。
由于您希望新的上下文foreach请求避免使用缓存对象,因此您不得将上下文注入存储库,而是使用方法调用从外部传递它,并使用工厂在服务或提供程序中创建它。
答案 1 :(得分:1)
要避免此异常,请在具有较长生命周期的类(操作过滤器,成员资格提供程序等)中使用DependencyResolver.Current.GetService()而不是注入属性。此方法不是测试友好的,但它允许您在使用InRequestScope()时访问当前http请求的数据上下文实例。
答案 2 :(得分: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));
}
}