我有一個使用Entity Framework 4.1和Ninject的MVC3應用程序。它使用標準的Repository模式,它在PerRequest的基礎上接受IUnitOfWork/DbContext(來自Ninject)。單身DbContext的自定義RoleProvider可能與MVC3網站中的PerRequest DbContext衝突
該網站在單用戶測試中運行良好。我們最近開始與2+用戶進行一些併發負載測試,並開始針對某些請求獲取此錯誤:
連接未關閉。連接的當前狀態正在連接。
System.Data.EntityException: The underlying provider failed on Open. --->
System.InvalidOperationException: The connection was not closed. The connection's current state is connecting.
at System.Data.ProviderBase.DbConnectionBusy.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.Open()
at System.Data.Objects.ObjectContext.EnsureConnection()
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Store.Security.StoreSecurityService.GetUserGroupRoles(String username) in C:\Dev\Store2\Trunk\Store.Security\StoreSecurityService.cs:line 57
at Store.Security.StoreSecurityService.GetRolesForUser(String username) in C:\Dev\Store2\Trunk\Store.Security\StoreSecurityService.cs:line 23
at Store.Security.StoreRoleProvider.GetRolesForUser(String username) in C:\Dev\Store2\Trunk\Store.Security\StoreRoleProvider.cs:line 37
at System.Web.Security.RolePrincipal.IsInRole(String role)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext)
at System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
如果這個問題是由具有實現MVC RoleProvider類,它需要訪問的DbContext,使調用數據庫自定義RoleProvider造成我想知道。
public class StoreRoleProvider : RoleProvider
{
public IStoreSecurityService StoreSecurityService { get; set; }
public StoreRoleProvider()
{
StoreSecurityService = DependencyResolver.Current.GetService(typeof(IStoreSecurityService));
}
public override string[] GetRolesForUser(string username)
{
return StoreSecurityService.GetRolesForUser(username);
}
}
本來,我們解決了IStoreSecurityService其中有一個的DbContext注入到它(PerRequest)的實例,但據我所知,RoleProvider僅在應用程序啓動創建一次,這樣的DbContext將被處置在請求結束時。
我想在這樣的構造特定實例:
public StoreRoleProvider()
{
StoreSecurityService = new StoreSecurityService(new DbContext());
}
但這會產生類似的錯誤。
LINQ查詢引發錯誤是不是特別難...
public IEnumerable<string> GetRolesForUser(string username)
{
var roles = (from user in _dbContext.Set<User>()
join userRole in _dbContext.Set<UserRole>()
on user.Id equals userRole.IserId
join role in _dbContext.Set<Role>()
on userRole.RoleId equals role.Id
where user.UserName == username && !userRole.IsDeleted
select role.Name).ToList<string>();
return roles;
}
我不明白爲什麼連接正在改變狀態這麼多。
任何想法,將感激地讚賞:)
可能的欺騙:http://stackoverflow.com/questions/12677975/what-could-cause-many-data-access-exceptions-using-ef-code-first-in-a-custom-rol 。 –
感謝您的鏈接。它是同樣的問題,但解決方案與我的問題不同。 –