简体   繁体   English

对实体框架的静态方法感到困惑

[英]Confused about static methods with Entity Framework

I'm calling the following from my controller: 我正在从控制器中调用以下命令:

public ViewResult Index()
{
    var users = SecurityHelpers.GetAllStaff();
    return View(users);
}

The method I'm calling to get all my users looks like this: 我要获取所有用户的方法如下所示:

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

My problem is that when I modify a staff member, such as by setting a disabled boolean, the method is bring back their old data (so the disabled user is still enabled). 我的问题是,当我修改工作人员时(例如通过设置禁用的布尔值),该方法将恢复其旧数据(因此仍启用了禁用的用户)。 I think this is because static functions are cached until the app pool recycles? 我认为这是因为静态功能一直缓存到应用程序池回收为止?

Is there a way to also get the latest data from this method without making it non-static? 是否有一种方法也可以从该方法中获取最新数据而又不会使其成为静态数据? (as there is a lot of code that will need to be changed to instatiate the object each time, and I don't think that's the right architecture) (因为每次都需要更改很多代码以使对象实例化,所以我认为这不是正确的体系结构)

I think this is because static functions are cached until the app pool recycles 我认为这是因为静态功能一直缓存到应用程序池回收为止

No. The problem is that you use a long-lived context ( db ) that you keep alive forever in a static variable, and this context is caching all the entities you are querying. 否。问题在于您使用了一个长期存在的上下文( db ),该上下文在一个静态变量中永久存在,并且此上下文正在缓存正在查询的所有实体。

There is a way to refresh the cached entities so that you don't get stale values, but the real problem here is that you really shouldn't be keeping a long-lived context like that. 有一种刷新缓存的实体的方法,这样您就不会获得过时的值,但是这里的真正问题是,您实际上不应该保留这样的长期存在的上下文。 It comes with this problem of stale data, and as the cache grows, you will also start noticing bad performance. 随之而来的是过时的数据问题,并且随着缓存的增长,您也将开始注意到性能下降。

Notice what the documentation says about how entities are returned from queries (emphasis mine): 注意文档中关于查询如何返回实体的内容 (重点是我的):

When results are returned from the database, objects that do not exist in the context are attached to the context. 从数据库返回结果时,上下文中不存在的对象将附加到上下文。 If an object is already in the context, the existing object is returned 如果上下文中已有一个对象,则返回现有对象

One viable alternative is to create the context as needed. 一种可行的选择是根据需要创建上下文。 Example: 例:

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

Depending on how your application is architected, you may be able to set it up so that you have a context instance per request instead. 根据应用程序的架构,您可能可以对其进行设置,以使每个请求都具有一个上下文实例。 That would be even better IMO. IMO会更好。 However you decide to do it, don't use a singleton context! 但是,您决定这样做,请不要使用单例上下文!

Static Entity Framework object also can cause loss of data . 静态实体框架对象也可能导致数据丢失 It might allow the program to remove records that source of FK even you have set the DELETE_RULE - No Action in the DB. 即使您已经在数据库中设置了DELETE_RULE-No Action,它也可能允许程序删除FK来源的记录。

That's why it is mandatory to use this code(user sstan's): 这就是为什么必须使用此代码(用户斯坦的)的原因:

    using(var db = new Context())
    {
        var users = db.Users
                .OrderBy(x => x.FirstName).ThenBy(x => x.LastName)
                .ToList();            
        return users;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM