对实体框架

时间:2016-09-20 00:59:40

标签: c# entity-framework

我正在从我的控制器中调用以下内容:

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;
    }
}

我的问题是,当我修改一个职员时,例如通过设置一个禁用的布尔值,该方法将恢复他们的旧数据(因此仍然启用了禁用的用户)。我认为这是因为在应用程序池回收之前缓存静态函数?

有没有办法从这个方法中获取最新数据而不使其成为非静态数据? (因为每次都需要更改很多代码来实例化对象,我不认为这是正确的架构)

2 个答案:

答案 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;
    }