问题
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