2015-06-04 73 views
1

好的,我有一個數據庫表1000行這是DDD規則嗎?

從這些我需要隨機提取4個條目。 這是一個商業規則。我可以很容易地在LINQ或SQL中做隨機的事情。但是我的Domain項目必須是獨立的,而不是引用任何其他項目。

所以我應該有一個列表,加載所有1000行並隨機提取4是DDD清理。

可以嗎?如果db-table有100k行呢?

+0

主鍵的順序是? –

+0

ID可以是1,2,5,7 ...(升序,但其中一些丟失)。不順序:)但是我得到你要去的地方,我可以創建一個新的列,我將確保連續順序並只傳遞視頻計數。 –

+1

只需在行計數中選擇四個隨機數,然後從SQL中選擇包含[[ROW_NUMBERs]](https://msdn.microsoft.com/zh-cn/library/ms186734.aspx)的行服務器。 –

回答

0

如果主鍵是連續的並且沒有中斷,那麼這對於100k或更高的表格會產生很大的性能好處。即使他們不是順序的,我相信你可以檢查一下,然後輕輕地重複以找到它。

基本上你會想通過獲得由ID記錄,以獲得該表的計數

var rowCount = db.DbSet<TableName>().Count(); //EF for pseudo 

然後在這個範圍內

var rand = new Random(); 
var randIds = Enumerable.Range(0,4).Select(i => rand.Next(0,rowCount).Array(); 

獲得4個隨機數字,然後遍歷(這也可以使用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); 
} 
0

建立在特拉維斯的代碼上,這應該適合你。它基本上獲得記錄數,生成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(); 
+0

這裏要考慮的一件事是'Skip'在大型表格中可能是一個非常昂貴的調用。 –

+0

@TravisJ如果您按主鍵進行排序,則不適用。 –

+0

我不知道它做了這種優化。 –