1

i am trying to show random products in view for each request, this OrderBy(r => Guid.NewGuid()) works fine, but i am trying to increase perfomance when table records are huge , so i used second option from here

my action:

public ActionResult ProductType(string id)
{
List<ProductsView> productlist = (from a in this.dbo.ProductTable
                                 join ca in dbo.Category on a.CategoryID equals ca.CategoryID
                                 where ca.Category == id 
                                 select new ProductsView()
                                 {
                                 CategoryID = c.CategoryID,
                                 Categorycount = c.Categorycount
                                 }).ToList<ProductsView>();

// here shuffle or mix products

int count = productlist.Count();
int index = new Random().Next(count);
ViewBag.Products = productlist.Skip(index).ToList();

 return View();

}

but when view returns some records are missing, eg:

first request count 4 index 1

shows 3 product in view

second request count 4 index 2

shows 2 product in view

third request count 4 index 3

shows 1 product in view

finally i have one more requirement can i show last inserted row in top and let other products be random ?

may i know what i am missing ?

any help would be great.

Community
  • 1
  • 1
Shaiju T
  • 6,201
  • 20
  • 104
  • 196
  • Well it's doing exactly what you've asked it to: it's skipping a random number of rows. Your requirements are really unclear here - what exactly do you mean by "random products"? If there are four products in total, how many do you want to display? – Jon Skeet Jun 10 '15 at 09:58
  • @Jon Skeet, actually i want to display 4 products but in random order for each request – Shaiju T Jun 10 '15 at 10:01
  • Right, well that's not what your code says to do at all, is it? Random *ordering* is entirely different from skipping elements entirely. Do you always want to show all the products? What if there are thousands? – Jon Skeet Jun 10 '15 at 10:10
  • @Jon Skeet, yes you are right, but what can be done ? right now we are planning to display all products – Shaiju T Jun 10 '15 at 10:15
  • 1
    Okay, so what do you mean by "last inserted rows in top" - how many do you want to be not-random? Just one? Everything in the last day? It sounds like you really need to think about your requirements very carefully before moving on to implementation. – Jon Skeet Jun 10 '15 at 10:19
  • @Jon Skeet, sorry for not saying the correct requirement, just one last added product should be at top and remaining random – Shaiju T Jun 10 '15 at 10:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80162/discussion-between-stom-and-jon-skeet). – Shaiju T Jun 10 '15 at 10:33

1 Answers1

1

Okay, so the updated requirements are:

  • Fetch all items
  • Ordering is random other than the first item, which should be the last one added

Firstly, get rid of your Skip call. You're not trying to skip anything. Just fetch all the products (possibly ordered - see below) into a list.

For the randomness part, I'd do that in the calling code, using a modified Fischer-Yates shuffle - there are numerous examples of that on Stack Overflow, such as here.

In this case, you probably want to get the most recent item to the start of the list and then just shuffle the rest of the list. That's easy enough to do with a slight modification to the shuffling code - but you need to get the most recent item to the start of the list first. You could either do that by using OrderByDescending(x => x.InsertionDate) (or whatever) in your LINQ query, or just fetch everything and find the latest row in an O(n) pass over the rows in memory. Using OrderByDescending will be simpler, but potentially slightly less efficient (as you don't really need full ordering).

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • first thank you so much for helping me out, i am new using extention helper, may i know how can i use it is it this way in action method `exthelper.Shuffle(productlist,range);` how to get and pass random range parameter – Shaiju T Jun 10 '15 at 11:27
  • 1
    @stom: You won't be able to use it as-is - you'll need to modify it to avoid moving the first element. I don't know what you mean by "random range parameter" - `rng` in my answer stood for "random number generator", not "range". See http://csharpindepth.com/Articles/Chapter12/Random.aspx for things to be aware of when creating/using `Random`. – Jon Skeet Jun 10 '15 at 12:19
  • thank you , i will check that and reply you in few days, really appreciate your time. – Shaiju T Jun 11 '15 at 05:54