如何将一个动作方法与ASP.NET MVC中的其他动作方法共享相同的数据

时间:2017-05-13 16:12:56

标签: asp.net-mvc asp.net-mvc-4 c#-4.0

  1. 当我调用我的管理控制器时 - 索引操作方法将获取所有用户详细信息
  2. 当我想再次选择特定用户时,我不想点击数据库。
  3. 两个动作方法相同的控制器,我正在使用模型弹出窗口显示详细信息。

    我的问题 我不想使用实体框架。 - 当admin表单加载时,我将获得所有用户详细信息,这是索引操作方法 - 基于用户ID,我需要显示特定用户,所以我不想要打到数据库已经我有所有用户的详细信息。详细说明如何获得另一种行动方法?

    我记得asp.net我使用session来全局共享数据。像那样的asp.net mvc可能吗?请帮帮我。

    由于

1 个答案:

答案 0 :(得分:3)

看起来你正在寻找缓存机制。对于简单的场景,我使用一个简单的静态变量,但我将它保存在一个单独的类中。假设你有一个像这样的User类:

public class User
{
    public string Id { get; set; }
    public string Name { get; set; }
}

你可以创建一个这样的类:

public static class UserCacheService
{
    private static IEnumerable<User> _users;
    private static readonly object lockObj = new object();

    public static IEnumerable<User> GetUsers()
    {
        lock (lockObj)
        {
            if (_users == null)
            {
                using (var db = new MyNiceDbContext())
                {
                    _users = db.Users.ToList();
                }
            }
            return _users;
        }
    }

    public static void InvalidateCache()
    {
        lock (lockObj)
        {
            _users = null;
        }
    }

}

然后,您可以在任何操作中获取共享用户,例如:

public class AdminController : Controller
{

    public ActionResult Index()
    {
        // the first time, it'll need to get users from DB (e.g with Entity Framework)
        var users = UserCacheService.GetUsers();
        return View();
    }

}

第一次,_users中的UserCacheService将为null,正如预期的那样,它需要从数据库加载用户。但是,无论您是否使用其他控制器,下一次都不会:

public class AnotherController : Controller
{

    public ActionResult Index(string userId)
    {
        // now, it won't load from DB anymore, because _users is already populated...
        var users = UserCacheService.GetUsers();
        var currentUser = users.Where(u => u.Id == userId).FirstOrDefault();
        if (currentUser != null)
        {
            // do something with the user...
        }
        return View();
    }

}

有时您的_users会再次成为null,例如当您在IIS中重新启动 ApplicationPool 时,UserCacheService已经准备好了如果是这种情况,则获取一次数据库。

小心三件事:

  1. 每当您将数据保存在内存中时(如_users),您就会消耗 您的服务器内存,可能会受到限制。不要开始尝试 将所有内容保存在内存中,只保存每次都知道的数据。
  2. 每当您更新用户的内容时,例如姓名,地址或其他内容,因为_users每次都无法从数据库获取,您需要调用UserCacheService.InvalidateCache()方法,以便强制下一次调用再次从数据库加载,从而确保你有_users最新。
  3. 这仅适用于简单的场景。如果您的应用程序分布在两个或更多服务器中,这将无法工作,因为每个服务器都有自己的内存,并且无法开箱即用。那时候你会期待像Redis这样的东西。虽然,我认为这不是你的情况。