My role provider looks like the class below (abridged). I am running on IIS Express, and SQL 2012 Express, from VS 2012, and I get a multitude of seemingly random exceptions in this role provider code.
public class Educ8RoleProvider : RoleProvider
{
private readonly Educ8DbContext _dbContext = new Educ8DbContext();
private readonly Authorization _authorization;
public Educ8RoleProvider()
{
_authorization = new Authorization(_dbContext);
}
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
try
{
base.Initialize(name, config);
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
throw;
}
}
public override bool IsUserInRole(string username, string roleName)
{
return GetRolesForUser(username).Any(r => r.ToLower() == roleName);
}
public override string[] GetRolesForUser(string username)
{
return _authorization.GetRolesForMember(username).Select(r => r.Name).ToArray();
}
}
Here is a sample of my Authorization
class:
public class Authorization
{
private readonly Educ8DbContext _dbContext;
private readonly IMemberRepository _memberRepository;
private readonly IRoleRepository _roleRepository;
private readonly IMemberRoleRepository _memberRoleRepository;
public Authorization(Educ8DbContext context)
{
_dbContext = context;
_memberRepository = new MemberRepository(_dbContext);
_roleRepository = new RoleRepository(_dbContext);
_memberRoleRepository = new MemberRoleRepository(_dbContext);
}
public IQueryable<Role> GetRoles()
{
return _roleRepository.ListAll();
}
public IQueryable<Role> GetRolesForMember(int memberId)
{
var roleIds = _memberRoleRepository.ListAll()
.Where(mr => mr.MemberId == memberId)
.Select(mr => mr.RoleId);
return _roleRepository.ListAll()
.Where(r => roleIds.Contains(r.Id));
}
}
I get about two to three of the following exceptions every hour. Restarting the project immediately solves the problem, until the next one.
- Not allowed to change the 'ConnectionString' property. The connection's current state is closed.
- The context cannot be used while the model is being created.
- The underlying provider failed on Open.
It may be worth noting that I have absolutely zero data access issues anywhere else in the project.
Any suggestions on what may be causing this would be most welcome.
Gert Arnold is on the right track with his comment. You have to realize that the RoleProvider
runs as a singleton. Each time you restart your app, it is causing a new instance of this class to be constructed. As long as your application is running, it keeps using this one single instance.
I used to get the same kinds of exceptions as in your question before I realized that this class runs as a singleton. After you have that knowledge, it is not difficult to make these exceptions go away:
public class Educ8RoleProvider : RoleProvider
{
//private readonly Educ8DbContext _dbContext = new Educ8DbContext();
//private readonly Authorization _authorization;
public Educ8RoleProvider()
{
//_authorization = new Authorization(_dbContext);
}
private Authorization GetAuthorization()
{
return new Authorization(new Educ8DbContext());
}
public override void Initialize(string name, NameValueCollection config)
{
try
{
base.Initialize(name, config);
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
throw;
}
}
public override bool IsUserInRole(string username, string roleName)
{
return GetRolesForUser(username)
.Any(r => r.ToLower() == roleName);
}
public override string[] GetRolesForUser(string username)
{
return GetAuthorization().GetRolesForMember(username)
.Select(r => r.Name).ToArray();
}
}
Essentially, you want to make sure that each method call on the RoleProvider
works with a brand new DbContext
instance. This way, the RoleProvider
singleton is not hanging onto a single DbContext
that gets stale.
来源:https://stackoverflow.com/questions/12677975/what-could-cause-many-data-access-exceptions-using-ef-code-first-in-a-custom-rol