为什么我的数据库上下文被处理

时间:2017-01-04 14:31:36

标签: c# asp.net-mvc entity-framework

正如我最近发表的大部分文章一样,我首先要说这对我来说是全新的,我处于理解的边缘。我正在处理现有的应用程序,并遇到了上述错误。

该应用程序是一个MVC应用程序,有3层,正在通过Swagger运行:

Rest

Services

DAL

在服务层DependencyConfig中,我在Register方法中执行以下操作,注册了上下文:

container.RegisterWebApiRequest<DbContext>(() => new LocalContext("name=DefaultConnection"));

到目前为止,这一切似乎都运行良好,因为应用程序的一部分是从数据库读取和写入 - 虽然这个应用程序中有很多东西,但我并不了解所有这些。

接下来,在Rest层上,我有以下内容:

public class AccountController : ApiController
{
    private readonly WindowsAuthenticationProvider _windowsAuthentication;
    private readonly AuthorizationManager _authorizationManager;
    private readonly IApplicationUserService _userService;
    private readonly IProfileService _profileService;
    private readonly IAccountLogsService _accountLogsService;

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="authorizationManager">Authorization Manager</param>
    /// <param name="windowsAuthentication">Enables windows reauthentication without a session</param>
    public AccountController(AuthorizationManager authorizationManager, WindowsAuthenticationProvider windowsAuthentication,
        IApplicationUserService userService, IProfileService profileService, IAccountLogsService accountLogsService)
    {
        _windowsAuthentication = windowsAuthentication;
        _authorizationManager = authorizationManager;
        _userService = userService;
        _profileService = profileService;
        _accountLogsService = accountLogsService;
    }

    /// <summary>
    /// Get logged in user details
    /// </summary>
    /// <remarks>Retrieves details of the currently logged in user</remarks>
    [Authorize]
    [HttpGet]
    [Route("")]
    [ResponseType(typeof(AccountDetailsModel))]
    public IHttpActionResult Details()
    {
        var userId = User.Identity.GetUserId<int>();

        var model = //...

        if (model.HasAccount)
        {
            var user = _authorizationManager.FindUser(User.Identity);
        }

        return Ok(model);
    }
 }

以及服务层:

public class AuthorizationManager
    {
        private readonly IApplicationUserService _userService;

        public ApplicationUser FindUser(IIdentity identity)
        {
            var userId = identity.GetUserId<int>();
            if (userId != 0)
            {
                return _userService.FindById(userId);
            }

            //...
        }
    }

最后也在服务层:

public class ApplicationUserService : UnitOfWork<LocalContext>, IApplicationUserService
    {
        private readonly UserManager<ApplicationUser, int> _userManager;
        private readonly RoleManager<ApplicationRole, int> _roleManager;

        /// <summary>
        /// Finds a user by id
        /// </summary>
        /// <param name="id">User id</param>
        /// <returns>ApplicationUser</returns>
        public ApplicationUser FindById(int id)
        {
            return _userManager.FindById(id);
        }
}

其中ApplicationUser是DAL图层上的模型。

我希望到目前为止这一切都有意义!

问题是当代码到达这一行时:

return _userManager.FindById(id);

它会抛出InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.

在我看来,它已经失去了上下文,例如数据库连接。

它似乎从寄存器方法中处理了DbContext - 但我不明白为什么?

如果我手动创建这样的上下文:

Context.Users.Find(id);

我能够检索所需的条目,但问题又发生在线下 - 而且我认为该应用程序的目的不是这样。

所以我的问题是,为什么要处理我的上下文,我怎么能阻止它呢?

单步执行代码并没有帮助,我的想法也没有。

1 个答案:

答案 0 :(得分:0)

问题与这条线有关:

container.Register<IUserStore<ApplicationUser, int>, UserStore <ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>>(Lifestyle.Scoped);

由于lifestlye.scoped,此时正在处理背景。

我需要将其添加到container

container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

来自这些说明:http://simpleinjector.readthedocs.io/en/latest/lifetimes.html#perwebrequest

仅在Web请求结束处理了对象