简体   繁体   English

实体框架6.1.3、2 Web应用程序1 SQL数据库,浏览器缓存问题

[英]Entity Framework 6.1.3, 2 Web Applications 1 SQL Database, Browser Cache Issues

The Problem : 问题

No matter how sure I am that my transactions are committed and the application can read the absolute latest from the database, sometimes when I refresh the application the changes aren't displaying the latest data and I suspect that the data is being cached in the browser! 不管我多么确定自己的事务已提交,并且应用程序可以从数据库中读取绝对最新的消息,有时当我刷新应用程序时,所做的更改不会显示最新数据,并且我怀疑数据正在缓存在浏览器中! This suspicion comes from loading the web application in another browser after the changes are made and seeing the changes. 怀疑来自于在进行更改后在另一个浏览器中加载Web应用程序并看到了更改。 I need to make it so that every time the page is refreshed, this data is not cached in the browser. 我需要这样做,以便每次刷新页面时,都不会在浏览器中缓存此数据。


Setup : 设置

One Web Application simply reads from the database, while AJAX calls are made client side to a REST API that adds, deletes, and updates the data. 一个Web应用程序仅从数据库中读取数据,而AJAX调用在客户端进行REST API的添加,删除和更新数据。

I have been doing a lot of research and the most valuable resource I have found on this was here: http://mehdi.me/ambient-dbcontext-in-ef6/ 我一直在做很多研究,而我发现的最有价值的资源是在这里: http : //mehdi.me/ambient-dbcontext-in-ef6/

My code that reads from the database uses this pattern: 我从数据库读取的代码使用以下模式:

public IEnumerable<Link> GetLinks(){
    using (var context = new MyContext()){
         foreach(var link in context.ChangeTracker.Entries())
         {
             link.Reload();
         }
         return context.Links.Where(x => x.UserId == this.UserId).ToList();
    }
}

An example of one of my operations that reads follows this pattern: 我的其中一项操作的示例如下所示:

    public int AddLink(string text, string url)
    {
        using (var context = new MyContext())
        {
            Link linkresult;
            using (var contextTransaction = context.Database.BeginTransaction())
            {
                var link = new Link()
                {
                    Text = text,
                    Url = url
                    UserId = this.UserId
                };

                linkresult = context.Links.Add(link);
                context.SaveChanges();
                contextTransaction.Commit();
            }
            return linkresult.Id;
        }
    }

Now as shown above, the context.SaveChanges() with the contextTransaction.Commit() I'm making sure that the data gets written to the database and is not cached at any level. 现在,如上所示,带有contextTransaction.Commit()的context.SaveChanges()我确保将数据写入数据库并且不会在任何级别上进行缓存。 I have confirmed this by using the Server Explorer and watching the content get updated real time. 我已经通过使用服务器资源管理器确认了这一点,并观看内容进行了实时更新。

I also think I have confirmed that my read will pull up the latest information from the database by loading the web application in another browser after the changes have been made, but I acknowledge that this may also be a caching issue that I am not aware of. 我还认为我已经确认,所做的更改之后,通过将Web应用程序加载到另一个浏览器中,我的读物将通过从另一个浏览器中加载Web应用程序来从数据库中获取最新信息,但是我承认这也可能是我不知道的缓存问题。

My last step is getting around the caching that happens in the browser. 我的最后一步是解决浏览器中发生的缓存。 I know chrome allows you to clear your app hosted data, but I don't know how to make certain data is not cached so that every time a request happens this code executes. 我知道chrome允许您清除应用程序托管的数据,但是我不知道如何确保不缓存某些数据,因此每次请求发生时,该代码都会执行。


More Details on the REST API : The Controller for the above example looks something nearly identical to this: 有关REST API的更多详细信息 :上面示例的控制器看起来与此几乎相同:

    public ActionResult AddLink(MyLink model)
    {
        IntegrationManager manager = new IntegrationManager(System.Web.HttpContext.Current.User);
        model.Id = manager.AddLink(model.Text, model.Url);
        return Json(model);
    }

The IntegrationManager is just a basic class that does not implement IDisposable because the context is created and disposed of during each transaction. IntegrationManager只是不实现IDisposable的基本类,因为上下文是在每次事务处理期间创建和处理的。 As can be seen, the AddLink is a member of the IntegrationManager class. 可以看出,AddLink是IntegrationManager类的成员。


More Details on the Web Application : The model for the view creates an IntegrationManager in it's constructor as a temporary variable to make the getLinks call as follows: 有关Web应用程序的更多详细信息 :视图的模型在其构造函数中创建一个IntegrationManager作为临时变量,以进行getLinks调用,如下所示:

    public Home(IPrincipal user, Cache cache)
    {
        this.HttpCache = cache;

        IntegrationManager _IntegrationManager = new IntegrationManager(user);
        this.Links = this.GetLinks(_IntegrationManager);

    }

AJAX Call : AJAX电话

          .on("click", "#btn-add-link", function (event) {
                var text = $("#add-link-text"),
                    url = $("#add-link-url");

                if (text.val().length > 0 && url.val().length > 0) {
                    var hasHttp = /^http.*$/.test(url.val());
                    if (!hasHttp) {
                        url.val("http://" + url.val());
                    }

                    $.ajax({
                        url: addLinkUrl,
                        type: "POST",
                        data: { Text: text.val(), Url: url.val() }
                    }).success(function (data) {
                        var newLink = $('<li class="ui-state-default deletable" id="link-' + data.Id + '"><a href="' + data.Url + '" target="_blank">' + data.Text + '</a></li>');

                        $("#user-links").append(newLink);

                        text.val("");
                        url.val("");

                    });

Okay, so I have found out how to make sure no caching happens. 好的,所以我找到了如何确保不进行缓存的方法。 The following is an attribute for the controller of the web application called NoCache. 以下是Web应用程序控制器的名为NoCache的属性。 To use it, your controller will need the attribute like this: 要使用它,您的控制器将需要如下属性:

using whatever.namespace.nocache.lives.in

[NoCache]

Here is the details of the attribute: 这是该属性的详细信息:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

I'm still looking into the details of whether or not I need everything that is included because it does increase the time the page takes to load significantly. 我仍在研究是否需要包含所有内容的细节,因为它确实增加了页面加载所需的时间。

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

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