0

I'm trying to use the predicate builder to get the LastVerifiedDate ordered in descending order by using the PredicateBuilder in LinqKit So far It didn't work out. Here's what I have tried so far:

var predicate = PredicateBuilder.New<Item>();
predicate.And(f => OrderByDescending(f.LastVerfiedDate)); // Not working code

Im okay to add to Cosmos Query aswell like below:

var response = _client.CreateDocumentQuery<T>(_tools.GetCollectionUri<T>(),
                 new FeedOptions
                 {
                 PartitionKey = new PartitionKey(partitionKey), MaxItemCount = requestCommand.PageSize,
                 RequestContinuation = requestCommand.Token
                 })

var docQuery = response.Where(predicate).OrderByDescending(f.LastVerfiedDate); // OrderByDescending not available

Question:

Can this be achievable using CreateDocumentQuery? Basically I need to fetch data in descending order based on LastVerifiedDate attribute. If so can someone provide code sample which I can try out?

Selaka Nanayakkara
  • 3,296
  • 1
  • 22
  • 42
  • Ordering is not a predicate here so rather no you can't but you should be able too simple append it to the query. `query.Where(predicate).OrderByDescending(f.LastVerfiedDate)`. – Ralf Jun 28 '23 at 07:56
  • There is no `query.where(predicate).OrderByDescending() ` available – Selaka Nanayakkara Jun 28 '23 at 08:08
  • That was an example you need to adapt to your code. – Ralf Jun 28 '23 at 08:12
  • `OrderByDescending(f.LastVerfiedDate)` is invalid. The correct expression is `OrderByDescending(f=>f.LastVerfiedDate)` . The method expects an expression that returns a sort key. It's not a predicate, ie an expression returning True/False – Panagiotis Kanavos Jun 28 '23 at 08:19
  • What's the actual problem anyway? The Cosmos code contains a normal LINQ query with a typo. LinqKit isn't used anywhere. If `T` is constrained by a type constraint to implement a type or interface with a `LastVerifiedDate` property, there's no need for a dynamic query – Panagiotis Kanavos Jun 28 '23 at 08:21
  • I need to query data by sorting on attribute `LastVerifiedDate ` which is DateTime in descending order @PanagiotisKanavos. – Selaka Nanayakkara Jun 28 '23 at 09:44
  • You do that with `OrderByDescending(f=>f.LastVerfiedDate)`. Not with `OrderByDescending(f.LastVerfiedDate)`. There's no `OrderByDescending(DateTime)` or `OrderByDescending(T)`. The definition is [OrderByDescending(...,Expression> keySelector)](https://learn.microsoft.com/en-us/dotnet/api/system.linq.queryable.orderbydescending?view=net-7.0#system-linq-queryable-orderbydescending-2(system-linq-iqueryable((-0))-system-linq-expressions-expression((system-func((-0-1)))))) – Panagiotis Kanavos Jun 28 '23 at 09:47
  • To your updated question - yes it can, if you use the correct method. `response.Where(predicate).OrderByDescending(f=>f.LastVerfiedDate);`. If you want to make your method generic on T, there should be a type constraint like `where T:IHasLastVerifiedDate`, eg `IEnumerable GetDocsByDate(...) where T:IHasLastVerifiedDate { ...}` – Panagiotis Kanavos Jun 28 '23 at 09:50

1 Answers1

0

I was basically able to achieve ordering data based on Expression via the below code. Posting it here for anyones reference.

My use case was to order the data based on DateTime parameter called LastVerifiedDate which I have from data fetched CreateDocumentQuery. I was able to achieve like below :

    public async Task<PagedResults<TResult>> GetPagedAsync<TResult>(Expression<Func<T, bool>> predicate, Expression<Func<T, DateTime>> orderedByDateAscending,
        PagedCommand<T> requestCommand, string partitionKey = null)
    {
        var response = string.IsNullOrWhiteSpace(partitionKey)
            ? _client
                .CreateDocumentQuery<T>(_tools.GetCollectionUri<T>(),
                    new FeedOptions
                        {MaxItemCount = requestCommand.PageSize, RequestContinuation = requestCommand.Token})
            : _client
                .CreateDocumentQuery<T>(_tools.GetCollectionUri<T>(),
                    new FeedOptions
                    {
                        PartitionKey = new PartitionKey(partitionKey), MaxItemCount = requestCommand.PageSize,
                        RequestContinuation = requestCommand.Token
                    });
        var docQuery = response.Where(predicate).OrderBy(orderedByDateAscending); // Pass it like this to OrderBy method
        var total = requestCommand.TotalRecords;
        if (requestCommand.Token == null && !requestCommand.HasMore)
        {
            total = docQuery.Count();
        }

        var query = docQuery.AsDocumentQuery();
        var list = await query.ExecuteNextAsync<TResult>();
        var pagedResult = new PagedResults<TResult>(requestCommand.PageSize, total, list.ResponseContinuation,
            query.HasMoreResults, requestCommand.PageIndex + 1, list.ToList());

        return pagedResult;
    }

Invoking the above method like below :

Expression<Func<StartPoints, DateTime>> orderByExpression = e=>e.LastVerfiedDate;    
    var results = await _myQueryRepository.GetPagedAsync<ItemDto>(predicate, orderByExpression, request);
Selaka Nanayakkara
  • 3,296
  • 1
  • 22
  • 42