EF + Repository ASP.NET MVC 3应用程序中的ObjectContext处理

时间:2011-04-29 17:40:24

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

所以,当我尝试通过The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. ObjectContext中的存储库访问OnActionExecuting时,我收到ActionFilterAttribute错误。

我的ActionFilterAttribute检查是否存在HTTP cookie。如果它存在,则使用数据库对其进行验证,刷新它的到期时间,然后将其添加到Controller ViewData集合中,以便ActionResult可以访问它。如果它不存在,则将用户重定向到登录页面。

过滤器一半有效,因为当HTTP cookie 存在并且它试图从数据库中抓取具体对象时,它会因上述错误消息而崩溃。

由于已有多少层,我将继续将代码发布给所有人,VerifyCookieAttribute.csCookieRepository.csRepository_1.cs。最后,虽然它可能没有任何区别,但错误发生在SelectSingle的{​​{1}}方法中。

依赖注入由Ninject 2.2.1.0提供。延迟加载目前已启用 ,但任一设置都会产生相同的错误。

无论如何,我很欣赏一些关于我所有这些问题出错的指导。在此先感谢您的帮助!

Repository_1.cs

更新

这是@jfar请求的堆栈跟踪:

// VerifyCookieAttribute.cs [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] internal class VerifyCookieAttribute : ActionFilterAttribute { [Inject] public CookieRepository Repository { private get; set; } private HttpRequestBase Request = null; private HttpResponseBase Response = null; private readonly bool Administration = false; private readonly bool Customers = false; private readonly string[] ExcludedPaths = new string[2] { "/Administration", "/Customers" }; public VerifyCookieAttribute( bool Administration, bool Customers) { this.Administration = Administration; this.Customers = Customers; } public override void OnActionExecuting( ActionExecutingContext ActionExecutingContext) { this.Request = ActionExecutingContext.HttpContext.Request; if (!this.ExcludedPaths.Contains(this.Request.Url.AbsolutePath)) { this.Response = ActionExecutingContext.HttpContext.Response; if (this.Exists()) { Cookie Cookie = this.Get(); this.Refresh(Cookie); ActionExecutingContext.Controller.ViewData.Add("Cookie", Cookie); if (this.Administration) { ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { area = "Administration", controller = "Administration", action = "Dashboard" })); } else if (this.Customers) { // Do Nothing }; } else if (!this.Exists() && !this.Response.IsRequestBeingRedirected) { if (this.Administration) { ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { area = "Administration", controller = "Administration", action = "Default" })); } else if (this.Customers) { ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { area = "Customers", controller = "Customers", action = "Default" })); }; }; }; } private bool Exists() { string Token = this.GetHttpCookieToken(); return (!String.IsNullOrEmpty(Token) && (Token.Length == 256)); } private Cookie Get() { string Token = this.GetHttpCookieToken(); Cookie Cookie = this.Repository.SelectSingle( c => (c.Token == Token)); return (Cookie); } private string GetHttpCookieToken() { if (this.Request.Cookies["NWP"] != null) { return this.Request.Cookies["NWP"]["Token"]; }; return (string.Empty); } private void Refresh( Cookie Cookie) { if (Cookie.RefreshStamp <= DateTime.Now.AddHours(1)) { this.Repository.RefreshCookie(Cookie.CookieId); this.SetHttpCookie(Cookie); }; } private void SetHttpCookie( Cookie Cookie) { this.Response.Cookies["NWP"]["Token"] = Cookie.Token; this.Response.Cookies["NWP"].Expires = Cookie.RefreshStamp.AddHours(1); } } // CookieRepository.cs public sealed class CookieRepository : Repository<Cookie> { [Inject] public CookieRepository( Entities Entities) : base(Entities, true) { } public void RefreshCookie( int CookieId) { this.Entities.ExecuteFunction("RefreshCookie", new ObjectParameter("CookieId", CookieId)); } } // Repository`1.cs public class Repository<TEntity> : IRepository<TEntity> where TEntity : class { protected readonly Entities Entities = null; private readonly IObjectSet<TEntity> EntitySet = null; [Inject] public Repository( Entities Entities) : this(Entities, true) { } [Inject] public Repository( Entities Entities, bool CreateEntitySet) { this.Entities = Entities; if (CreateEntitySet) { this.EntitySet = this.Entities.CreateObjectSet<TEntity>(); }; } public virtual void Delete( TEntity TEntity) { this.EntitySet.DeleteObject(TEntity); } public virtual void Insert( TEntity TEntity) { this.EntitySet.AddObject(TEntity); } public virtual IQueryable<TEntity> Select() { return this.EntitySet; } public virtual IQueryable<TEntity> Select( Expression<Func<TEntity, bool>> Selector) { return this.EntitySet.Where(Selector); } public virtual bool SelectAny( Expression<Func<TEntity, bool>> Selector) { return this.EntitySet.Any(Selector); } public virtual IList<TEntity> SelectList() { return this.EntitySet.ToList(); } public virtual IList<TEntity> SelectList( Expression<Func<TEntity, bool>> Selector) { return this.EntitySet.Where(Selector).ToList(); } private IList<TEntity> SelectOrderedList( bool Ascending, params Expression<Func<TEntity, IComparable>>[] Orderers) { IOrderedQueryable<TEntity> Queryable = null; foreach (Expression<Func<TEntity, IComparable>> Orderer in Orderers) { if (Queryable == null) { Queryable = (Ascending ? this.EntitySet.OrderBy(Orderer) : this.EntitySet.OrderByDescending(Orderer)); } else { Queryable = (Ascending ? Queryable.ThenBy(Orderer) : Queryable.ThenByDescending(Orderer)); }; }; return (Queryable.ToList()); } public virtual IList<TEntity> SelectOrderedList( params Expression<Func<TEntity, IComparable>>[] Orderers) { return this.SelectOrderedList(true, Orderers); } public virtual IList<TEntity> SelectOrderedDescendingList( params Expression<Func<TEntity, IComparable>>[] Orderers) { return this.SelectOrderedList(false, Orderers); } public virtual TEntity SelectSingle( Expression<Func<TEntity, bool>> Selector) { return this.EntitySet.Single(Selector); } public virtual void Update() { this.Entities.SaveChanges(); } public virtual IEnumerable<TEntity> Where( Expression<Func<TEntity, bool>> Selector) { return this.EntitySet.Where(Selector); } }

1 个答案:

答案 0 :(得分:2)

我假设您使用的是mvc 3.

  

在以前的ASP.NET MVC版本中,   每个请求都会创建操作过滤器   除了少数情况。这种行为   从来都不是保证行为但是   仅仅是一个实现细节和   过滤器的合同是   认为他们是无国籍的。在ASP.NET中   MVC 3,过滤器缓存更多   积极。因此,任何习惯   不正确存储的动作过滤器   实例状态可能会被破坏。

这意味着为每个请求创建属性,因此任何InRequestScope注入都不起作用。您需要注入IServiceProvider并在每个请求中获取存储库或手动创建新上下文。