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

本文关键字:静态方法 实体 框架 | 更新日期: 2023-09-27 18:07:39

我从控制器调用以下代码:

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

我的问题是,当我修改工作人员时,例如通过设置禁用布尔值,方法是恢复他们的旧数据(因此禁用的用户仍然是启用的)。我认为这是因为静态函数被缓存,直到应用程序池回收?

是否有一种方法,也从这个方法获得最新的数据,而不使其非静态?(因为每次都需要修改大量代码来初始化对象,而且我认为这不是正确的架构)

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

我认为这是因为静态函数被缓存,直到应用程序池回收

。问题是,您使用了一个长期存在的上下文(db),您将其永久地保存在静态变量中,并且该上下文正在缓存您正在查询的所有实体。

有一种方法可以刷新缓存的实体,这样你就不会得到过时的值,但这里真正的问题是你真的不应该像那样保持一个长期存在的上下文。它带来了数据陈旧的问题,并且随着缓存的增长,您也会开始注意到糟糕的性能。

注意文档中关于如何从查询返回实体的说明(强调我的):

当从数据库返回结果时,上下文中不存在的对象被附加到上下文中。如果对象已经在上下文中,则返回现有对象

一个可行的替代方法是根据需要创建上下文。例子:

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

根据您的应用程序的架构,您可以将其设置为每个请求都有一个上下文实例。在我看来那就更好了。无论你决定怎么做,都不要使用单例上下文!

静态实体框架对象也会导致丢失数据。它可能允许程序删除FK源的记录,即使您已经在DB中设置了DELETE_RULE - No Action。

这就是为什么必须使用以下代码(用户sstan的):

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