2016-05-10 142 views
0

我努力減少管理存儲過程和所遇到的這個不知道如何(或者)可以成功地移植到實體框架:如何在EF中刪除記錄時返回刪除的記錄列?

-- select out filename so the caller can delete the file from the filesystem 
SELECT SystemFileName 
FROM File 
WHERE FileId = @fileId 

-- now delete 
DELETE 
FROM File 
WHERE FileId = @fileId 

基本上,PROC一個id,返回文件它將刪除的記錄的名稱,然後刪除該行。調用代碼然後具有文件名以執行任何文件系統清除,從而減少孤立文件的可能性。

現在使用Entity Framwork,我可以找到所有的文件並執行刪除操作,但如果我在循環中執行此操作,效率會非常低下。

我可以嘗試記錄我的嘗試,但它比任何編譯的代碼更僞代碼。

+0

你也想避免執行原始的sql命令,據我所知? – Evk

+0

從EF DbSet 中選擇要刪除的所有File對象,並將其存儲在列表中。遍歷列表並刪除每一個,或者我認爲有一個'RemoveRange'方法。 SaveChanges在你的DbContext上,然後你可以遍歷你的List並刪除文件 – Nkosi

+0

@Evk可能,如果我看不到proc的一個明智的選擇,我可能只是保持proc。 –

回答

1
// Select all the File objects from EF DbSet<File> that you want to delete and store in a List<File>. 
var toDelete = context.Files.Where(predicate).ToList(); 
//loop through the list and remove each one or i think there is a RemoveRange method. 
var deleted = context.Files.RemoveRage(toDelete); 
//SaveChanges on your DbContext 
if(context.SaveChanges() == toDelete.Count) { 
    //and then you can loop through your List and delete the files from system 
    deleted.ToList().ForEach(file => { 
     var fileInfo = new FileInfo(file.SystemFileName); 
     if(fileInfo.Exists) { 
      fileInfo.Delete(); 
     } 
    }); 
} 
+0

假設說,如果每個文件行都包含大量列,那麼這意味着要返回整行以便作爲謂詞傳遞給RemoveRange? –

+0

是的,這意味着要返回整行以便作爲參數傳遞給'RemoveRange'。在EF中,您將刪除整個對象,以便在某個時候檢索該實體。 – Nkosi

+0

所以我採取了這種方法,我不完全高興你需要整行,但我會採取它的簡單。 –

1

假設你有少於4000條記錄刪除使用何不

1)選擇要刪除 2)存儲這些結果在數組中的ID和文件名/列表 3)刪除所有記錄IN子句

// get all of the records to be deleted 
var records = context.Files.Where(x => x.Name.Contains("delete-me")).Select(x => new {x.Id, x.Name}).ToList(); 

// mark all of our files to be deleted 
context.Files.RemoveAll(x => records.Contains(x.Id)); // not sure if this line is correct as I am writing this in notepad, but it will give you a good enough idea 

// execute our save, which will delete our records 
context.Save(); 

// return the list of records that have been deleted back to the caller 
return records; 
+0

4000是一個(理智?)任意的數量還是有技術原因,我想如果有更多的記錄,我想考慮另一種方法? –

+0

Phil,4000是IN語句在SQL Server中可以處理的最大操作數。如果你做的超過4000,那麼你需要有某種批處理機制 – Kane

+0

感謝您的澄清,如果不僅對我而言,但其他任何人都會發現這一點。 –

0

說實話,我會認爲這是一個批量操作而不是EF(或其他奧姆斯爲此事)一個偉大的候選人。我不確定哪個更重要,簡化查詢或使用EF。但是,如果你想簡化查詢,你可以執行這樣的事情,並同時讀取受影響的刪除值

DELETE 
OUTPUT deleted.SystemFileName -- or OUTPUT deleted.* 
FROM File 
WHERE FileId = @fileId