How to Move Zero Qty Products to the end of List when i have a PagedList<Products>?

ε祈祈猫儿з 提交于 2020-01-03 05:35:06

问题


I have a method in my controller which returns a PagedList to my category-page View that contains Products (based current Page-Number and Page-Size which user has selected) from SQL Server stored-procedure like blow :

var products = _dbContext.EntityFromSql<Product>("ProductLoad",
pCategoryIds,
pManufacturerId,
pOrderBy,
pageIndex,
pageSize).ToList(); // returning products based selected Ordering by.
var totalRecords = pTotalRecords.Value != DBNull.Value ? Convert.ToInt32(pTotalRecords.Value) : 0;
var allPrd= new PagedList<Product>(products, pageIndex, pageSize, totalRecords);

An Example of sending parameters to db stored-procedure is :

("ProductLoad",
[1,10,13],
[653],
"Lowest Price",
 2,
 64) // so it returns second 64 products with those category-ids and Brand-ids sorting by lowest to highest price

It's working fine , but what i am trying to do is always sending products with 0 quantity to the end of list.

For example : if i had 10k products which 2k of them have 0 quantity , i need to show this 8k products first and then 2k unavailable products in the end of list)

what i have tried so far is always loading All products without page-size and page-index first then send zero qty products to the end of the list by this and finally Pagedlist with fixing page size :

 ("ProductLoad",
 [1,10,13],
 [653],
 "Lowest Price",
  0,
  10000) // fixed page size means loading all products   

 var zeroQty= from p in products
                    where p.StockQuantity==0
                    select p;

  var zeroQtyList= zeroQty.ToList();
  products = products.Except(zeroQtyList).ToList();
  products.AddRange(zeroQtyList);

  var totalRecords = pTotalRecords.Value != DBNull.Value ? Convert.ToInt32(pTotalRecords.Value) : 0;
  var allPrd= new PagedList<Product>(products, pageIndex, 64, totalRecords); 

It cause all zero qty Products goes to the end of list.

But it always loads all products that is not a good idea and for sure not an optimized way , sometime users get page loading time-out, (because category-page show 64 products in every page-index-number) every time user opens a page in the website, all products would loads and it cause delay in loading page.

Is there anyway to solve this problem (have a PagedList which contains all more than zero qty products first and 0 qty products second) without changing stored-procedure? (fixing loading page delays)

P.S : The reason i avoid changing stored-procedure is it has already too much join,temp-table Union and Order by.

Any help would be appreciated.


回答1:


You will need to the use the ROW_NUMBER function in your stored procedure.

This is an example of how I have done this before. Hopefully you will be able to adapt it to your SP.

--temp table to hold the message IDs we are looking for
CREATE TABLE #ids (
     MessageId UNIQUEIDENTIFIER
    ,RowNum INT PRIMARY KEY
);

--insert all message IDs that match the search criteria, with row number
INSERT INTO #ids
SELECT m.[MessageId]
      ,ROW_NUMBER() OVER (ORDER BY CreatedUTC DESC)
  FROM [dbo].[Message] m WITH (NOLOCK)
 WHERE ....

DECLARE @total INT;
SELECT @total = COUNT(1) FROM #ids;

--determine which records we want to select
--note: @skip and @take are parameters of the procedure
IF @take IS NULL
    SET @take = @total;
DECLARE @startRow INT, @endRow INT;
SET @startRow = @skip + 1;
SET @endRow = @skip + @take;

-- select the messages within the requested range
SELECT m.* FROM [dbo].[Message] WITH (NOLOCK)
INNER JOIN #ids i ON m.MessageId = i.MessageId
WHERE i.RowNum BETWEEN @startRow AND @endRow;



回答2:


OrderByDescending could be useful to fix it. Like below:

List<Product> SortedList = products.OrderByDescending(o => o.StockQuantity).ToList();


来源:https://stackoverflow.com/questions/59383555/how-to-move-zero-qty-products-to-the-end-of-list-when-i-have-a-pagedlistproduct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!