存储查找值的最佳方法

时间:2011-04-08 19:16:22

标签: c# asp.net optimization

我长期以来一直有这个问题,并想在这里寻求人群的智慧。

在我的应用程序中,允许使用10个用户角色。它是一个ASP.NET MVC2应用程序。每个控制器方法只能由特定的用户角色访问。

为了实现这个,我创建了一个UserRoleType枚举。

 public enum UserRoleType
 {
        SystemAdministrator = 1,
        SeniorLevelExecutive = 2,
        SeniorManager = 3,
        JuniorManager = 4,
        SeniorAdmin = 5,
        JuniorAdmin1 = 6,
        JuniorAdmin2 = 7,
        SeniorAppraiser = 8,
        JuniorAppraiser = 9,
        SeniorResearch = 10   
 }

这些值与数据库中的whats(UserRole表有10行)相匹配。

用户的UserRoleId也存储在[User]表中。一旦用户登录,我们从数据库中获取用户的roleId,并将其与上述枚举相匹配。例如,如果用户的roleId为4,则表示他/她是初级经理。

此应用程序现在尚未投入生产。我看到的唯一缺点就是当我们上线时,如果由于某种原因,用户角色类型表中的值与Enum不匹配,我们将遇到大麻烦。有哪些替代方案?或者我应该专注于确保我们在数据库中具有匹配的值。任何帮助将受到高度赞赏。

非常感谢!

6 个答案:

答案 0 :(得分:1)

我的意见是,如果您不能相信自己在DB和Config文件中的配置,那么无论如何你都是小溪。只需确保您的数据库记录将该值作为特定列值,而不是自动生成的行ID。

答案 1 :(得分:1)

如果RoleID的值不在枚举范围内,请不要登录用户。

我会向管理员发送电子邮件以解决问题。

答案 2 :(得分:0)

我这样做但是向DB添加了适当的约束,约束描述将读者引导到枚举。

答案 3 :(得分:0)

我不确定你应该使用像枚举那样的静态数据结构来模拟像动态表这样的动态元素。拥有UserRole实体类和UserRoleCollection集合类会不会更好?这样,用户角色集可以更加动态。当然,只要您的代码使用这些数据结构,您就必须确保构建一个故障安全机制,如果遇到未知的用户角色,则会导致对特定资源的访问始终被拒绝。当然,如果以某种方式将未知角色输入数据库,代码将生成描述性消息。

答案 4 :(得分:0)

答案 5 :(得分:0)

一个简单的方法是将一个Name字段添加到UserRole表中,并在应用程序启动时迭代枚举,按ID查找UserRole,并确保名称与UserRoleType.ToString()匹配。您应该能够在不进行任何重大代码更改的情况下实现此目的。

private void VerifyUserRoles()
{
    foreach (UserRoleType role in Enum.GetValues(typeof(UserRoleType)))
    {
        string dbName = /* SELECT Name FROM UserRole WHERE UserRoleId = (int)role */;
        if(role.ToString() != dbName) throw new Exception();
    }
}

更复杂的方法是根本没有枚举。如果要使角色列表完全由数据库驱动,则使UserRoleType成为具有私有构造函数的类,并让它执行数据库读取以创建对象列表。 (我想这个模式有一个名称,但不确定它是什么。)显然,这将是对现有代码的一个更重要的改变。

public class UserRole
{
    static List<UserRole> roles = new List<UserRole>();

    static UserRole()
    {
        foreach (/* SELECT * FROM UserRole */)
        {
            roles.Add(new UserRole(...));
        }
    }

    private UserRole(...){...}

    // Permissions that the role consists of.
    private bool CanEditEverything { get; private set; }

    // Use this whenever you need to display a list of UserRoles.
    public static ReadOnlyCollection<UserRole> AllUserRoles { get { return roles.AsReadOnly(); } }

    // If you still need to explicitly refer to a role by name, rather than 
    // its properties, do these and set them in the static constructor.
    public static UserRole SystemAdministrator { get; private set; }
}