2016-03-02 1 views
1

Я ищу для кэширования дорогостоящего запроса с помощью ServiceStack.ServiceStack Caching

Моя идея заключается в следующем

Шаг 1: Просмотр кэш всю базу данных для Redis, который истекает через день

Шаг 2: Когда клиент вызывает API маршрута «/ кэшированные/остатки/{Дата}», служба возвращает только часть вида кэшированной базы данных.

Чтобы осуществить это, я использую

запросов и ответов Модели

[Route("/balances", "GET", Notes = "A call to Db which extracts the entire Db balance view")] 
public class GetBalances : IReturn<GetBalancesResponse> 
{ 

} 

[Route("/cached/balances/{Date}", "GET", Notes = "Gets a subsection of cached balanced")] 
public class GetCachedBalances : IReturn<GetBalancesResponse> 
{ 
    public int Date { get; set;} 
    public int? EntityId { get; set;} 
} 

public class GetBalancesResponse 
{ 
    public List<BalanceView> Result { get; set; } 
} 

Service Interface

public object Any(GetBalances request) 
{ 
    var balances = Db.Select<BalanceView>(); 
    return new GetBalancesResponse {Result = balances }; 
} 

public object Any(GetCachedBalances request) 
{ 
     GetBalances balancesRequest = request.ConvertTo<GetBalances>(); 

    // get the cached response 
     var allBalances = (CompressedResult)base.Request.ToOptimizedResultUsingCache(
       this.CacheClient, "urn:balances",() => { 
        var service = this.ResolveService<BalanceServices>(); 
        return (GetBalancesResponse)service.Any(balanceRequest); 
       }); 

      // filter the results -> this does not work! 
      var filterBalances = response.Response.ConvertTo<GetBalancesResponse>().Result.Where(Ar => Ar.Date == request.Date && (Ar.EntityId == request.EntityId || request.EntityId == null)); 

    return new GetBalancesResponse {Result = filteredBalances}; 
} 

Фильтрация остатков не работает, как я не могу для преобразования сжатого результата в ResponseDto.

ответ

1

Возможно, у меня есть ответ на мой вопрос.

The ServiceInterface GetCachedBalances могут быть отфильтрованы в соответствии с ниже

public object Any(GetCachedBalances request) 
    { 
    GetBalances balancesRequest = request.ConvertTo<GetBalances>(); 

    // cache everything 
    var filteredCachedResponse = (CompressedResult)base.Request.ToOptimizedResultUsingCache(
      this.CacheClient, "urn:balances",() => { 
       var service = this.ResolveService<BalanceServices>(); 
       return ((GetBalancesResponse)service.Any(balanceRequest)).Result.Where(Ar => Ar.Date == request.Date && (Ar.EntityId == request.EntityId || request.EntityId == null)); 
      }); 

    // filter cached response 
    var filteredResponse = base.Cache.Get<GetBalanceResponse>("urn:balances"). 
        Result.Where(Ar => Ar.Date == request.Date && (Ar.EntityId == request.EntityId || request.EntityId == null)); 

     return filteredResponse; 
    } 
+0

Обратите внимание на CompressedResult инкапсулирует сжатые сериализованные байты в окончательном виде, что они написаны непосредственно к ResponseStream в. Таким образом, вы не можете десериализации его обратно в DTO вам нужно либо хранить/извлекать DTO в кеше напрямую (т. е. не использовать ToOptimizedResult), либо выполнять любую обработку, прежде чем кэшировать результат, как вы здесь делаете. – mythz

+0

@mythz - только что понял, что мой собственный ответ не совсем то, что я ищу. Я надеялся кэшировать весь DbView, а затем возвращать только часть кеша. Однако это не представляется возможным, поскольку единственным способом сделать это было бы как-то десериализовать его обратно в DTO и фильтровать его в соответствии с параметрами запроса. –

+1

Вы можете кэшировать и извлекать DTO, обратившись непосредственно к base.Cache. – mythz