看起来您正在寻找一种缓存机制。对于简单的场景,我使用一个简单的静态变量,但我将它保存在一个单独的类中。假设您有一个这样的 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;
}
}
}
然后你可以让你的 shared 用户在任何操作中,像这样的任何控制器:
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();
}
}
第一次,UserCacheService 中的_users 将为空,并且正如预期的那样,它需要从数据库加载用户。但是,下次它不会,无论您是否使用另一个控制器:
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 已经准备好获取数据库一次,如果这是案例。
注意三件事:
- 每当您将数据保存在内存中(如
_users)时,您都在消耗
您的服务器内存,这可能是有限的。不要开始尝试
将所有内容保存在内存中,只保留您知道每次都需要的数据。
- 每当您更新用户中的某些内容时,例如姓名、地址或其他内容,由于
_users 不会每次都从数据库中获取,您需要调用 UserCacheService.InvalidateCache() 方法,以强制下一次调用再次从数据库加载,从而确保 _users 是最新的。
- 这仅适用于简单的场景。如果您的应用程序分布在两台或多台服务器上,这将不起作用,因为每台服务器都有自己的内存,而且它们无法开箱即用地共享它。那时你会期待像 Redis 这样的东西。不过,我认为这不是你的情况。