好的,所以我有一个数据库表1000行。
从这些我需要随机提取4个条目。这是一条业务规则。我可以很容易地在LINQ或SQL中做随机的事情。但我的领域项目必须是独立的,不引用任何其他项目。
所以我应该在那里有一个列表,用所有的1000行加载它并随机提取4以DDD-clean。
这样可以吗?如果db-table有100k行呢?
如果主键是顺序的并且没有中断,那么这将为100k或更大的表带来很大的性能优势。即使它们不是连续的,我相信你可以检查一下,然后轻轻地迭代找到它。
基本上你会想要得到一个表的计数
var rowCount = db.DbSet<TableName>().Count(); //EF for pseudo
然后在这个范围内得到4个随机数字
var rand = new Random();
var randIds = Enumerable.Range(0,4).Select(i => rand.Next(0,rowCount).Array();
然后迭代通过id获取记录(这也可以使用包含和id来完成,我不确定哪个更快,但只有4个查找应该快速执行)。
var randomRecords = new List<TableName>();
foreach(int id in randIds)
{
var match = db.DbSet<TableName>().Find(id);
//if the id is not present, then you can iterate a little to find it
//or provide a custom column for the exact record as you indicate in comments
while(match != null)
{
match = db.DbSet<TableName>().Find(++id);
}
randomRecords.Add(match);
}
基于Travis的代码,这应该可以为您工作。它基本上获得记录的计数,生成4个随机数,然后请求表中的第n条记录并将其添加到结果列表中。
var rowCount = db.TableName.Count();
var rand = new Random();
var randIds = Enumerable.Range(0,4).Select(i => rand.Next(0,rowCount));
var randomRecords = new List<TableName>();
foreach(int id in randIds)
{
var match = db.TableName
.OrderBy(x=>x.id) // Order by the primary key -- I assumed id
.Skip(id).First();
randomRecords.Add(match);
}
你也可以这样做,如果你有一个自动递增的id字段为主键。需要注意的是,这不是一个固定时间函数,因为您不确定可能需要多少个循环:
var idMax = db.TableName.Max(t=>t.id);
var rand = new Random();
var randomRecords = new List<TableName>();
while(randomRecords.Count()<4)
{
var match = db.TableName.Find(rand.Next(0,idMax));
if(match!=null)
randomRecords.Add(match);
}
如果你不关心绝对随机性(这是非常非常不随机的,有些东西比其他东西更重要),但这是最快的方法,只需要一次数据库访问:
var idMax = db.TableName.Max(t=>t.id);
var rand = new Random();
var randIds = Enumerable.Range(0,4).Select(i => rand.Next(1,idMax));
var query=db.TableName.Where(t=>false);
foreach(int id in randIds)
{
query=query.Concat(db.TableName.OrderBy(t=>t.id).Where(t=>t.id>=id).Take(1));
}
var randomRecords=query.ToList();