我有一个使用Breeze查询数据的应用程序。我想首先检查本地缓存,然后检查服务器缓存,如果没有返回结果(我遵循John Papa的SPA快速启动课程)。但是,我发现我的逻辑存在缺陷,我不确定如何解决。假设我有10个与我的查询匹配的项目。
情况1 (有效):我转到列表页面(页面A),显示全部10.点击服务器作为缓存为空并将全部10添加到缓存。然后转到显示缓存中找到的1个结果(页面B)的页面。一切都很好。
情境2 (问题):我转到首先显示1条记录的页面(页面B)。然后我转到我的列表页面(页面A),它检查缓存并找到1条记录,因为这行(if (recordsInCache.length > 0)
)它退出并且只显示1条记录。
我不知何故需要知道服务器(9)上有更多不在缓存中的记录,即。这个查询的总记录实际上是10,我有1,因此我必须为其他9个命中服务器。
以下是我对Page 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);
}
这是我对Page 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;
}
任何建议表示赞赏......
答案 0 :(得分: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,这样您就可以知道是否拥有所有实体。
答案 1 :(得分:0)
我在去年更多地考虑过这个问题(之后从Durandal + Breeze转移到Angular + Breeze:在Angular中你可以使用
轻松缓存服务调用return $resource(xyz + params}, {'query': { method:'GET', cache: true, isArray:true }}).query(successArrayDataLoad, errorDataLoad);
我猜Angular会缓存此查询的 params 并知道它何时已经存在。因此,当我将此方法切换为使用Breeze时,我会丢失此功能,并且每次都会触发所有列表调用。
所以这里真正的问题是列表数据。单个实体总是可以检查本地缓存,如果没有返回任何内容,则检查服务器(因为您期望正好1)。
但是,列表数据因参数而异。例如,如果我有GetGames调用,它接受CreatedByUserId,每次我提供一个新的CreatedByUserId时,我必须返回服务器。
所以我认为我真正需要做的就是缓存我的List调用是为每个调用缓存Key,它是QueryName和Params的组合。
例如,UserID 1为GetGames1,UserId为2为GetGames2。
逻辑是:检查Angular缓存以查看此会话之前是否已进行此调用。如果有,则首先检查本地缓存。如果没有返回任何内容,请检查服务器。
如果没有,请检查服务器是否为本地缓存MIGHT中有一些数据用于此查询,但不保证是完整集。
唯一的另一种方法是每次首先点击服务器以获取Query + Params的计数,然后点击本地缓存并比较计数,但效率更低。
思想?