ASP.NET MVC 3 / Razor - 奇怪的缓存问题

时间:2012-02-20 16:06:51

标签: c# linq linq-to-sql caching

我正在使用LinqToSql查询从数据库中选择一个组列表并显示一个表。我编写了一个自定义类来缓存此查询的结果,以获得更好的性能。麻烦的是,每当我实现缓存类时,我都会从输出语句中获得奇怪的追加行为。

我的结果以

格式输出
Test Group (1)

其中“Test Group”是名称,(1)是该组中的成员数。这是将计数附加到名称(从视图)

的代码
<td>@group.group_name (@group.num_total)</td>

当我从实时linq查询返回组中提取它时,一切都按预期工作。

但是,当我使用我的缓存类时,每个连续的页面加载都会将数字添加到组标题的末尾:

Test Group (1) (1) (1) (1) (1) (1)

这只发生在我使用缓存类(包括在下面)时。我一直在缓存类,我没理由看到为什么会发生这种情况。

我可以想到这个问题的几个解决方法,所以它不是一个显示阻止,但我很好奇软糖正在发生什么。有任何想法吗?

缓存类:

public class Cache
{
    public static int user_id { 
        get { return 
            Convert.ToInt32(
                Membership.GetUser(
                    HttpContext.Current.User.Identity.Name
                ).ProviderUserKey
            ); 
        } 
    }

    public static void GetGroups_InvalidateCache()
    {
        if (HttpContext.Current.Cache["GetGroups_" + user_id] != null)
            HttpContext.Current.Cache.Remove("GetGroups_" + user_id);
    }

    public static ICollection<Groups> GetGroups()
    {
        if (HttpContext.Current.Cache["GetGroups_" + user_id] == null)
        {
            using(DBContext db = new DBContext())
            {

                var Groups = (from g in db.Groups 
                        where g.user_id == user_id 
                        select g).ToList(); 

                HttpContext.Current.Cache.Insert(
                        "GetGroups_" + user_id, 
                        Groups, 
                        null, 
                        DateTime.Now.AddMinutes(5), 
                        TimeSpan.Zero
                );
            }
        }
        return HttpContext.Current.Cache["GetGroups_" + user_id] 
                    as ICollection<Groups>;
    }
}

更新

我现在已经实现了Adam Tuliper和Paul Tyng关于使用using子句调用数据上下文的建议,使用ToList()结束linq语句并使用ICollection而不是{{1 }}。问题仍然存在。

另一个有趣的观察:只有当我导航到另一个页面并返回时才会出现问题。如果我只是刷新页面,则不会发生(虽然我刷新时仍然保留以前的任何数字)

1 个答案:

答案 0 :(得分:2)

不要返回IQueryable,而是尝试使用IEnumerable并使用

using(DBContext db = new DBContext())
{
var Groups = 
                (from g in db.Groups 
                where g.user_id == user_id 
                select g).ToList(); 
...
}

同样处理上下文中的上下文(使用using子句)

ToList()强制执行“now” - 我认为你可能会延迟执行问题