4

我有一个使用 Breeze 来查询数据的应用程序。如果没有返回结果,我想先检查本地缓存,然后再检查服务器缓存(我遵循了 John Papa 的 SPA 快速入门课程)。但是,我发现了我的逻辑中的一个缺陷,我不确定如何修复。假设我有 10 个项目与我的查询匹配。

情况 1(可行):我转到显示所有 10 个的列表页面(页面 A)。因为缓存为空,所以命中服务器并将所有 10 个添加到缓存中。然后转到显示在缓存中找到的 1 个结果(页面 B)的页面。所以一切都很好。

情况2(问题):我首先转到显示1条记录的页面(页面B)。然后我转到我的列表页面(页面 A),它检查缓存并找到 1 条记录,并且由于这条线 ( if (recordsInCache.length > 0)) 它退出并仅显示 1 条记录。

我不知何故需要知道服务器(9)上有更多不在缓存中的记录,即。这个查询的总记录实际上是 10,我有 1 因此我必须为其他 9 打服务器。

这是我对页面 A 的查询:

function getDaresToUser(daresObservable, criteria, forceServerCall)
{
    var query = EntityQuery.from('Dares')
        .where('statusId', '!=', enums.dareStatus.Deleted)
        .where('toUserId', '==', criteria.userId)
        .expand("fromUser, toUser")
        .orderBy('deadlineDate, changedDate');

    return dataServiceHelper.executeQuery(query, daresObservable, false, forceServerCall);
}

这是我对页面 B 的查询(单项)

function getDare(dareObservable, criteria, forceServerCall)
{
    var query = EntityQuery.from('Dares')
        .expand("fromUser, toUser")
        .where('dareId', '==', criteria.dareId);

    return dataServiceHelper.executeQuery(query, dareObservable, true, forceServerCall);
}



function executeQuery(query, itemsObservable, singleEntity, forceServerCall)
{
    //check local cache first
    if (!manager.metadataStore.isEmpty() && !forceServerCall)
    {
        var recordsInCache = executeLocalQuery(query, itemsObservable, singleEntity);
        if (recordsInCache.length > 0)
        {
            callCompleted();
            return Q.resolve();
        }
    }

return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

}

function executeLocalQuery(query, itemsObservable, singleEntity)
{
    var recordsInCache = manager.executeQueryLocally(query);
    if (recordsInCache.length > 0)
    {
        processQueryResults(recordsInCache, itemsObservable, singleEntity, true);
    }
    return recordsInCache;
}

任何建议表示赞赏...

4

2 回答 2

1

如果您只想访问服务器进行比较,那么在某些时候(加载您的应用程序或点击列表页面时)调用 inlineCount 以比较服务器上的总数与您在此答案 stackoverflow.com 中显示的内容/questions/16390897/counts-in-breeze-js/…

在查询单个记录时可以创造性地使用它的一种方法是这样的 -

在您的视图模型或等于总数的地方设置一些变量

var totalCount = 0;

当您查询单个记录时,获取内联计数 -

var query = EntityQuery.from('Dares')
    .expand("fromUser, toUser")
    .where('dareId', '==', criteria.dareId)
    .inlineCount(true);

totalCount = data.inlineCount;在获得总项目列表时设置相同的内容,只需将 totalCount 设置为 inlineCount 然后也可以始终知道是否拥有所有实体。

于 2013-08-12T13:37:43.933 回答
0

去年我一直在考虑这个问题(并且已经从 Durandal + Breeze 转移到 Angular + Breeze :在 Angular 中,您可以使用轻松缓存服务调用

return $resource(xyz + params}, {'query': { method:'GET', cache: true, isArray:true }}).query(successArrayDataLoad, errorDataLoad);

我猜 Angular 缓存了这个查询的参数并且知道它什么时候已经有了。因此,当我将此方法切换为使用 Breeze 时,我会失去此功能,并且每次都会触发我的所有 List 调用。

所以这里真正的问题是列表数据。单个实体始终可以检查本地缓存,如果没有返回任何内容,则检查服务器(因为您期望正好为 1)。

但是,列表数据因参数而异。例如,如果我有一个接收 CreatedByUserId 的 GetGames 调用,那么每次我提供一个新的 CreatedByUserId 时,我都必须返回服务器。

所以我认为我在这里真正需要做的是缓存我的 List 调用是缓存每个调用的 Key,它是 QueryName 和 Params 的组合。

例如,GetGames1 用于 UserID 1,然后 GetGames2 用于 UserId 2。

逻辑是:检查 Angular 缓存以查看之前是否在此会话中进行过此调用。如果有,则先检查本地缓存。如果没有返回,请检查服务器。

如果没有,请检查服务器,因为本地缓存可能有一些用于此查询的数据,但不能保证是完整集。

唯一的另一种解决方法是每次首先访问服务器以获取该 Query + Params 的计数,然后访问本地缓存并比较计数,但这样效率较低。

想法?

于 2014-11-15T07:03:11.340 回答