Search code examples
breezebreeze-sharp

BreezeSharp - Query with parameters against the local cache


I am trying to execute query with parameters against local cache or server (if nothing is found in cache).

public async Task<List<T>> Get(IDictionary<string, object> parameters, string resourceName = "", FetchSource fetchSource = FetchSource.None)
{
    try
    {
        var query = resourceName == string.Empty ? EntityQuery.From<T>().WithParameters(parameters) : EntityQuery.From<T>(resourceName).WithParameters(parameters);
        var queryResult = await this.ExecuteQuery(query, fetchSource);
        var result = queryResult.ToList();
        return result;

    }
    catch (Exception e)
    {
        return new List<T>(); // return empty result instead
    }
}

FetchSource is our enum:

public enum FetchSource
{
    None = 0,

    FromServer = 1,

    FromCache = 2,

    FromCacheOrServer = 3
}

And here is ExecuteQuery method:

protected async Task<IEnumerable<T>> ExecuteQuery(EntityQuery<T> query, FetchSource fetchSource = FetchSource.None)
        {
            //...
            if (fetchSource == FetchSource.FromCacheOrServer)
            {
                var result = query.ExecuteLocally(this.EntityManager);  // Throws error
                if (result != null && result.Any())         
                {
                    return result;
                }

                return await query.Execute(this.EntityManager);
            }
            //...
        }

When I try to execute query locally this exception is thrown:

{"Unable to cast object of type 'WhereEnumerableIterator`1[StanleySteemer.Nimbus.Client.Common.Model.Proxy.RouteOrder]' to type 'DataServiceOrderedQuery[StanleySteemer.Nimbus.Client.Common.Model.Proxy.RouteOrder]'."}

Although I couldn't find anything in docs specifically regarding to this subject, I have implemented similar functionality in BreezeJS which was working without issue(UPDATE: it doesn't work correctly):

    findWithParametersInCacheOrServer = function (parameters, recordsLimit) {
        var query = breeze.EntityQuery
            .from(resourceName)
            .withParameters(parameters);

        var r = executeCacheQuery(query);
        if (r) {
            if (r.length > recordsLimit) {
                return Q.resolve(r);
            }
        }

        return executeQuery(query);
    };

    function executeCacheQuery(query) {
        return entityManagerProvider.manager().executeQueryLocally(query);
    }

Data architecture in JavaScript is similar to TempHire example.

Is this a known issue? Is there any workaround for it?


Solution

  • Not sure I understand, neither breeze.js nor breeze.sharp can automatically perform a 'local cache query' that involves parameters. This is because the interpretation of the parameters is only really defined on the server and not on the client.

    It sounds as though what you have done is define a custom implementation of your specific 'with parameters' query in breeze.js that completely bypasses Breeze's internal implementation. Is this correct?