这是DDD规则吗?

时间:2015-06-04 17:28:57

标签: c# linq domain-driven-design

好的,我有一个 1000行的数据库表。

从这些我需要随机提取4个条目。 这是一项商业规则。我可以轻松地在LINQ或SQL中做随机的事情。但是我的Domain项目必须是独立的,而不是引用任何其他项目。

所以我应该在那里有一个列表,加载所有1000行并随机提取4为DDD-clean。

这可以吗?如果db-table有100k行怎么办?

2 个答案:

答案 0 :(得分:0)

如果主键是顺序的而不是中断,那么这将为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获取记录(这也可以使用contains和id来完成,我不确定哪个更快但只有4个find应该快速执行)。

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);
} 

答案 1 :(得分:0)

基于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);
}

你也可以这样做, IF 你有一个自动增量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();