登录后在会话中加载大量数据

时间:2014-01-06 02:10:38

标签: c# asp.net session loading

我有一些数据需要在用户登录后存储在某处,我需要的是:

1. A list of customers
2. US States list

现在就是这样。现在,客户的名单可以继续不断增长,甚至在加载之后,显然美国国家也没有。

目前我在login.aspx页面上用户登录并验证了所有内容后,我进入我的SQL数据库并将所有客户和美国状态加载到Session变量中。现在这可以工作,虽然它确实需要一点时间,但因为在任何时候只有大约3个用户测试该网站它不会影响。但据我所知,当大约50多个用户的公司开始使用它甚至是客户时,这可能是一个问题。那么最好的方法是什么呢?为什么呢?提前谢谢。

PS。如果这不是一个有效的问题,请告诉我,我会把它删除,我只是不知道在哪里问这个并得到一些有用的反馈。

1 个答案:

答案 0 :(得分:1)

安德烈,

是否可以(而不是使用会话)来缓存数据。这可以通过各种缓存技术(IE System.Web.Caching,MemoryCahce)以多种方式完成。

随着用户增长\缩小,您可以同时修改数据库和缓存实例。当用户请求用户列表(状态)时,将评估缓存列表。如果未设置缓存列表,则重新构建缓存列表。

你可以做点什么。 (基本示例)

public class UserCache : IEnumerable<User>
{
    /// <summary>
    /// const cache string
    /// </summary>
    const string userCacheString = "_userCacheList";

    /// <summary>
    /// current list of users
    /// </summary>
    public static UserCache Current
    {
        get
        {
            if (HttpContext.Current == null)
                throw new Exception("NO CONTEXT");
            var userList = HttpContext.Current.Cache[userCacheString] as UserCache;
            if (userList == null)
            {
                userList = new UserCache();
                HttpContext.Current.Cache[userCacheString] = new UserCache();
            }
            return userList;
        }
    }

    /// <summary>
    /// default constructor
    /// </summary>
    public UserCache()
    {
    }

    /// <summary>
    /// the list of users
    /// </summary>
    List<User> users;

    /// <summary>
    /// adds a user
    /// </summary>
    /// <param name="user"></param>
    public void Add(User user)
    {
        if (this.Contains(user))
            return;
        this.users.Add(user);
    }

    /// <summary>
    /// removes a user
    /// </summary>
    /// <param name="user"></param>
    public void Remove(User user)
    {
        if (this.Contains(user))
            return;
        this.users.Remove(user);
    }

    /// <summary>
    /// clears a user
    /// </summary>
    public void Clear()
    {
        this.users = null;
    }



    /// <summary>
    /// fills the users from the database
    /// </summary>
    void fillUsers()
    {
        this.users = new List<User>();
        //TODO: Get from DB
    }

    /// <summary>
    /// gets the enumerator
    /// </summary>
    /// <returns></returns>
    public IEnumerator<User> GetEnumerator()
    {
        if (this.users == null)
            fillUsers();
        foreach (var user in users)
            yield return user;
    }

    /// <summary>
    /// gets the enumerator
    /// </summary>
    /// <returns></returns>
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

public class User
{
    public string UserName { get; set; }

    public Guid UserID { get; set; }

    public string Email { get; set; }
}

从这里开始,用户管理(添加\删除用户)可以调用UserCache来根据需要修改其集合。如(psudo代码)

public class UserManager
{
    public void Register(string userName, string email)
    {
        //TODO: Register in DB.
        UserCache.Current.Add(new User
        {
            UserID = Guid.NewGuid(),
            Email = email,
            UserName = userName
        });
    }
}

您可以随时拨打UserCache.Current来获取当前用户列表。

只是一个想法。

编辑:回复Simon Halsey评论。

在我从IEnumerable&lt;&gt;继承的示例中接口而不是List&lt;&gt;接口。这是个人偏好,并支持课程的“定义”。在我解释之前,这不是唯一的方法,而只是实现结果的概念方式。

在示例中,方法Clear()通过将内部列表user设置为null来清除内部列表。在IEnumerable<>实现GetEnumerator()方法中,首先检查内部列表是否为空。如果内部列表为null,则调用fillUsers()方法以从数据库中检索所有用户。

如果此示例继承自List&lt;&gt;那么List&lt;&gt;的Clear()方法将被调用并清除列表(删除所有项目),但列表不为空。因此,在调用Clear()方法后枚举列表将导致没有用户。现在可以使用List&lt;&gt;重写。实施如下。您唯一需要做的就是覆盖Clear()方法和构造函数来加载用户。如。。

public class UserListCache : List<User>
{
    /// <summary>
    /// const cache string
    /// </summary>
    const string userCacheString = "_userCacheList";

    /// <summary>
    /// current list of users
    /// </summary>
    public static UserListCache Current
    {
        get
        {
            if (HttpContext.Current == null)
                throw new Exception("NO CONTEXT");
            var userList = HttpContext.Current.Cache[userCacheString] as UserListCache;
            if (userList == null)
            {
                userList = new UserListCache();
                HttpContext.Current.Cache[userCacheString] = new UserListCache();
            }
            return userList;
        }
    }

    /// <summary>
    /// default constructor
    /// </summary>
    public UserListCache()
    {
        this.fillUsers();
    }

    /// <summary>
    /// clear the list
    /// </summary>
    public new void Clear()
    {
        base.Clear();
        this.fillUsers();
    }

    /// <summary>
    /// fills the users from the database
    /// </summary>
    void fillUsers()
    {
        //TODO: Get from DB
    }
}

现在这两种方法都不比另一种好(并且解决方案可能不够)。