2014-01-08 60 views
0

基本上,我在DESC創建的順序中列出名爲'ServerName'的所有服務器。例如,如果我有50個,我需要獲得40個serverIds的列表,以便它們可以被刪除;這樣我只保留最新的10個記錄(服務器)創建。這裏是簡單的SQL代碼:使用Row_Number()將SQL代碼轉換爲LINQ C#代碼

Delete ContosoServers Where serverId In 
    (
    Select 
    serverId 
    From 
    (
     Select 
     serverId 
     ,row_number() Over(Order By created desc) as recordNumber 
     From 
     UDS.ContosoServers 
     Where 
     name = 'ServerName' 
    ) ServerRecords 
    Where recordNumber > 10 
) 

我想我需要創建一些匿名類型(serverId,recordNumber)的列表。一旦我得到我可以從11到50的列表循環並刪除所有服務器記錄,保持1到10這是最新的。

我想出了這個解決方案,但我認爲是太多的代碼。在SQL中非常簡單,但在LINQ中看起來需要更多工作。我只是想避免所有這些循環,這裏是:

private static void DeleteOldRecords(string serverName) 
    { 
     const int numberOfRecordsToKeep = 10; 

     using (var context = new MyContext()) 
     { 
      var servers = context.ContosoServers 
           .Where(n => n.name == serverName) 
           .OrderByDescending(o => o.created) 
           .Select(s => new { s.serverId }).ToList(); 

      //skip the first 10 rows and delete the rest 11,20... 
      int i = 0; 
      foreach (var s in servers) 
      { 
       if (i > numberOfRecordsToKeep - 1) 
       { 
        //delete row 
        var entityToDelete = context.ContosoServers.Find(s.serverId); 
        if (context.Entry(entityToDelete).State == EntityState.Detached) 
        { 
         context.ContosoServers.Attach(entityToDelete); 
        } 
        context.ContosoServers.Remove(entityToDelete); 
       } 
       i++; 
      } 
      context.SaveChanges(); 
     } 

任何想法如何改善?這似乎並沒有 「雅」 :-)

謝謝

+0

這可能會幫助 - 從相關的列表:http://stackoverflow.com/a/1183599/745969 – Tim

回答

1

假設你正在使用LINQ to SQ,試試下面

DataClasses1DataContext上下文=新DataClasses1DataContext()的代碼;

 var d = (from s in context.ContosoServers 
       orderby s.created descending 
       select s).Take(10); 

     context.samples.DeleteAllOnSubmit(d); 
     context.SubmitChanges(); 
+0

將實際刪除它們是我想保留的那些10個最新的行。 – Max

+0

'orderby s.created'(不降序)和'Skip(10)'。 –

+0

我認爲由DESC訂購併跳過(10)將是答案,你不覺得嗎?我想保留最新的10行並刪除其他所有內容 – Max