2010-05-28 12 views
2

J'utilise LINQ to NHibernate, et une déclaration HQL je peux faire quelque chose comme ceci:Linq to NHibernate, ordre par Rand()?

string hql = "from Entity e order by rand()"; 

Andi t sera commandé de façon aléatoire, et je aimerais savoir le lien Comment puis-je faire la même chose déclaration avec Linq à Nhibernate?

J'essaie ceci:

var result = from e in Session.Linq<Entity> 
      orderby new Random().Next(0,100) 
      select e; 

mais il génère une exception et ne fonctionne pas ...

est-il une autre manière ou d'une solution?

Merci

Vive

Répondre

3

Je suppose que LINQ to NHibernate est incapable de convertir l'appel Random.Next à SQL ...

Une option serait de trier les résultats après vous les récupérer à partir la base de données:

var rand = new Random(); 
var query = from e in Session.Linq<Entity> 
      select e; 
var result = from e in query.AsEnumerable() 
      orderby rand.Next(0,100) 
      select e; 

Notez que vous devez utiliser une seule instance de Random, parce que la graine est basée sur le nombre actuel de ticks; Si vous créez plusieurs instances de Random avec un intervalle très court, elles auront la même origine et généreront la même séquence. Quoi qu'il en soit, trier une collection basée sur un nombre aléatoire n'est pas une bonne idée, car le tri ne sera pas stable et pourrait théoriquement durer éternellement. Si vous devez mélanger les résultats, vous pouvez utiliser l'algorithme Fisher-Yates:

var result = Session.Linq<Entity>().ToArray(); 
var rand = new Random(); 
for(int i = result.Length - 1; i > 0; i--) 
{ 
    int swapIndex = rand.Next(i + 1); 
    var tmp = result[i]; 
    result[i] = result[swapIndex]; 
    result[swapIndex] = tmp; 
}