What is the best (and fastest) way to retrieve a random row using Linq to SQL when I have a condition, e.g. some field must be true?
You can do this at the database, by using a fake UDF; in a partial class, add a method to the data context:
partial class MyDataContext {
[Function(Name="NEWID", IsComposable=true)]
public Guid Random()
{ // to prove not used by our C# code...
throw new NotImplementedException();
}
}
Then just order by ctx.Random()
; this will do a random ordering at the SQL-Server courtesy of NEWID()
. i.e.
var cust = (from row in ctx.Customers
where row.IsActive // your filter
orderby ctx.Random()
select row).FirstOrDefault();
Note that this is only suitable for small-to-mid-size tables; for huge tables, it will have a performance impact at the server, and it will be more efficient to find the number of rows (Count
), then pick one at random (Skip/First
).
for count approach:
var qry = from row in ctx.Customers
where row.IsActive
select row;
int count = qry.Count(); // 1st round-trip
int index = new Random().Next(count);
Customer cust = qry.Skip(index).FirstOrDefault(); // 2nd round-trip