我正在从我的控制器中调用以下内容:
public ViewResult Index()
{
var users = SecurityHelpers.GetAllStaff();
return View(users);
}
我打电话给我所有用户的方法如下:
public class SecurityHelpers
{
private static Context db = new Context();
public static IQueryable<ApplicationUser> GetAllStaff()
{
var users = db.Users
.OrderBy(x => x.FirstName).ThenBy(x => x.LastName);
return users;
}
}
我的问题是,当我修改一个职员时,例如通过设置一个禁用的布尔值,该方法将恢复他们的旧数据(因此仍然启用了禁用的用户)。我认为这是因为在应用程序池回收之前缓存静态函数?
有没有办法从这个方法中获取最新数据而不使其成为非静态数据? (因为每次都需要更改很多代码来实例化对象,我不认为这是正确的架构)
答案 0 :(得分:3)
我认为这是因为在应用程序池回收之前缓存静态函数
没有。问题是你使用一个长期存在的上下文(db
),你永远在一个静态变量中保持活着,这个上下文缓存你正在查询的所有实体。
有一种方法可以刷新缓存的实体,这样你就不会得到陈旧的值,但这里真正的问题是你真的不应该保持这样长寿的上下文。它伴随着陈旧数据的问题,随着缓存的增长,你也会开始注意到糟糕的性能。
注意documentation says about how entities are returned from queries(强调我的):
从数据库返回结果时,上下文中不存在的对象将附加到上下文。 如果对象已在上下文中,则返回现有对象
一种可行的替代方案是根据需要创建上下文。例如:
public class SecurityHelpers
{
public static IList<ApplicationUser> GetAllStaff()
{
using(var db = new Context())
{
var users = db.Users
.OrderBy(x => x.FirstName).ThenBy(x => x.LastName)
.ToList();
return users;
}
}
}
根据应用程序的架构方式,您可以对其进行设置,以便每个请求都有一个上下文实例。这将是更好的IMO。无论你决定这样做,都不要使用单例上下文!
答案 1 :(得分:0)
静态实体框架对象也会导致数据丢失。即使您已经在数据库中设置了DELETE_RULE-No Action,它也可能允许程序删除FK来源的记录。
这就是为什么必须使用此代码(用户斯坦的)的原因:
using(var db = new Context())
{
var users = db.Users
.OrderBy(x => x.FirstName).ThenBy(x => x.LastName)
.ToList();
return users;
}