# Using static management class to control db transactions through an EF6

I have the class below to manage my specific implementation of a membership system using entity framework 6.1

Is the use of static access correct in this case? as far as I understood that EF context is not thread-safe so I'm instantiating one with every call through the using statement. My second question, is the use of Boolean variable okay to signal failure in db transactions? an important point about this class is that it's going to be used quite frequently as the authentication wont rely on any session established with the user, it's also important to note that the users of this system will be quite limited.

Edit: I'm aware I can use the new identity system or any of the membership providers offered by ASP.NET but this custom provider is quite specific to a Windows authentication system and the use of any cookie-based system is not possible.

public static class AccountManager
{
private enum Role { User, Comment, CommentControl, Sysadmin }

public static bool IsUserInRole(string username, string role)
{
using (var ctx = new AccountsDbCtx())
{
var status = false;
if (foundAcc.Any())
{
var s = foundAcc.SingleOrDefault();
if (s != null)
{
var exitingRole = s.Roles.Where(x => x.Name.Equals(role, StringComparison.InvariantCultureIgnoreCase));
if (exitingRole.Any())
{
status = true;
}
}
}
return status;
}
}

{
using (var ctx = new AccountsDbCtx())
{
var result = true;
if (!foundAcc.Any())
{
result = false;
}
return result;
}
}

{
using (var ctx = new AccountsDbCtx())
{
var status = false;

try
{
var newAcc = new Account
{
Active = true,
};
ctx.SaveChanges();

status = true;
}
catch
{ }

return status;
}
}

{
}

{
}

{
}

private static bool AssignRole(string accountName, Role role)
{
using (var ctx = new AccountsDbCtx())
{
var completed = false;
var roleToAssign = ctx.Roles.SingleOrDefault(x => x.Role1 == (int)role);

try
{
var currentAccount = ctx.Accounts.SingleOrDefault(x => x.Username.Contains(accountName));

if (currentAccount != null && roleToAssign != null) currentAccount.Roles.Add(roleToAssign);

ctx.SaveChanges();

completed = true;

}
catch
{}

return completed;
}
}
}

-
If you're using .NET 4.5, then there are new ASync methods for all of your query methods, which will allow you to multi-thread calls to the database. –  krillgar Apr 14 '14 at 2:52

umm yes, you could do it that way.

as far as I understood that EF context is not thread-safe so I'm instantiating one with every call through the using statement

Where did you read this? I'm not denying it it's just that I have not read this before and I haven't experienced too many problems with using EF in the case of one instance per request.

My second question, is the use of Boolean variable ok to signal failure in db transactions

Maybe. But how are you going to know what actually went wrong? All that's going to happen is you know something went wrong but when it comes to diagnosing it you will be at a dead end because you have swallowed the exception (so to speak). Given that your exceptions seeming to be handling cases such as the database offline, or connection issues I think it would be best to bubble those up as that would be a core system fault and you would want to know more info.

Here's an alternative solution using a non-static class and sharing the Database context between methods.

NOTE: I would actually consider removing the default empty constructor and IDisposable if you were using an IOC framework to instantiate the context as that would be responsible for your instance lifetime. However I'm not sure how your Account Manager would be created.

public class AccountManager : IDisposable
{
private enum Role { User, Comment, CommentControl, Sysadmin }

public AccountManager(AccountsDbCtx dbContext)
{
this.dbContext = dbContext;
}

public AccountManager() : this(new AccountsDbCtx())
{
}

public void Dispose()
{
dbContext.Dispose();
{

public bool IsUserInRole(string username, string role)
{

if(account == null)
{
return false;
}

var existingRole = account.Roles.Where(x => x.Name.Equals(role, StringComparison.InvariantCultureIgnoreCase));

return existingRole.Any();
}

{
}

{
{
Active = true,
});

dbContext.SaveChanges();

}

{
}

{
}

{
}

{
}

private bool AssignRole(string accountName, Role role)
{
// Why would a role not exist in our database?
var roleToAssign = dbContext.Roles.Single(x => x.Role1 == (int)role);
var currentAccount = dbContext.Accounts.SingleOrDefault(x => x.Username.Contains(accountName));

if (currentAccount == null)
return false;

dbContext.SaveChanges();

return IsUserInRole(accountName, role);
}
}

-
Great points sir, thanks a lot for your help. –  Meldar Apr 13 '14 at 23:21
about the pre-fetch of the role object, I have the following schema [Account]1--m[AccountRole]m--1[Role] . EF did not simply allow me to create my role object and submit it with the account object or that's at least what happened when I tried it, the record simply does not get inserted. I had to pre-fetch my role before hand. –  Meldar Apr 13 '14 at 23:34
@Meldar Sorry I don't quite understand what you mean? Is something I suggested not working (Which could very well be the case) –  dreza Apr 13 '14 at 23:53
@Meldar oh, and just for your reference. If you let the question sit un-accepted for a few days you are more likely to get a few other people commenting who might also have great ideas, thoughts or even better comments. Might help you out even more.... –  dreza Apr 13 '14 at 23:54
@Meldar oh, yes My comment was around did we need to use SingleOrDefault. Cause if the role is always going to exist using Single would be clearer in that we expect it to always be there. Sorry if I wasn't clear in my query. –  dreza Apr 14 '14 at 0:00