Biarity / Sieve

⚗️ Clean & extensible Sorting, Filtering, and Pagination for ASP.NET Core
Other
1.21k stars 131 forks source link

CanSort() is returning duplicates when there are objects with the same values but different ids with the fields marked as sortable #99

Open BlueCC8 opened 3 years ago

BlueCC8 commented 3 years ago

While testing the pagination using the below classes I encountered the following problem. When I make a request with the following parameters:

And then change the page to 2, I can see that one object with the same id and values from the first page is in the page 2. When I looked into the DB with Mongo Compass I saw that the only difference between my entries is that I have some entries that have the Active field false or true and the id.

I suspect that CanSort() cannot sort correctly and creates duplicates when there are fields with the same values.

I was able to solve this issue by adding a custom sort as below

 public IQueryable<StatusReason> Address(IQueryable<Customer> source, bool useThenBy, bool desc)
        {
            var result = useThenBy ?
           ((IOrderedQueryable<Customer>)source).ThenBy(p => p.Address) : 
               IOrderedQueryable<TEntity> source.OrderBy(p => p.Address)
               .ThenBy(p => p.Name)
               .ThenBy(p => p.Active);

            return result;

        }

It's kind of weird to have same values for multiple objects but issues might happen in the DB. If somebody knows how to bypass this issue while using the CanSort() please let me know. Any suggestion is welcomed and thank you for your time.

Here is the Customer class

public class Customer: EntityBase
    {

        public string Name{ get; set; }
        public string Address{ get; set; }
        public bool Active{ get; set}
    }

Here is the SieveProcessor

public class CustomerSieveProcessor : SieveProcessor
    {

        public CustomerSieveProcessor(IOptions<SieveOptions> optionsParameters)
            : base(optionsParameters)
        {

        }

        protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
        {
            mapper.Property<Customer>(c => c.Name)
            .CanSort()
            .CanFilter();
            mapper.Property<Customer>(c => c.Address)
            .CanSort()
            .CanFilter();
            mapper.Property<Customer>(c => c.Phone)
            .CanSort()
            .CanFilter();
            mapper.Property<Customer>(c => c.Active)
            .CanSort()
            .CanFilter();
            return mapper;
        }
    }
hasanmanzak commented 3 years ago

As I understand Active field should be added to sorts in the first place by default. I think this is not a bug that sieve should handle, rather it is a bussiness logic concern.