Linq Orderby random ThreadSafe for use in ASP.NET

前端 未结 5 1907
春和景丽
春和景丽 2020-11-29 05:23

i\'m using Asp.net MVC with Sharp Architecture.

I have this code:

return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
                     


        
相关标签:
5条回答
  • 2020-11-29 06:06

    Probably best to write your own extension method to do it.

    public static class Extensions
    {
        static readonly Random random = new Random();
    
        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
        {
            return Shuffle(items, random);
        }
    
        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items, Random random)
        {
            // Un-optimized algorithm taken from
            // http://en.wikipedia.org/wiki/Knuth_shuffle#The_modern_algorithm
            List<T> list = new List<T>(items);
            for (int i = list.Count - 1; i >= 1; i--) 
            {
                int j = random.Next(0, i);
                T temp = list[i];
                list[i] = list[j];
                list[j] = temp;
            }
            return list;
        }
    }
    
    0 讨论(0)
  • 2020-11-29 06:08

    One way to achieve efficiently is to add a column to your data Shuffle that is populated with a random int (as each record is created).

    The query to access the table then becomes ...

    Random random = new Random();
    int seed = random.Next();
    result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);
    

    This does an XOR operation in the database and orders by the results of that XOR.

    Advantages:-

    1. Efficient: SQL handles the ordering, no need to fetch the whole table
    2. Repeatable: (good for testing) - can use the same random seed to generate the same random order
    3. Works on most (all?) Entity Framework supported databases

    This is the approach used by my home automation system to randomize playlists. It picks a new seed each day giving a consistent order during the day (allowing easy pause / resume capabilities) but a fresh look at each playlist each new day.

    0 讨论(0)
  • 2020-11-29 06:11

    You can do this in T-Sql as described here. I don't think you can do it in linq without loading the whole result set into memory and then throwing most of it away, which you do not want to do.

    0 讨论(0)
  • Random random = new Random();
    return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
                    .OrderBy(x => r.Next())
                    .Take(50).ToList();
    
    0 讨论(0)
  • 2020-11-29 06:23

    How about this?

    return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
      .OrderBy (x => Guid.NewGuid())
      .Take(50).ToList();
    
    0 讨论(0)
提交回复
热议问题