2016-05-10 107 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