Reputation: 7062
I have built a simple file manager, that pulls data from two tables, Folders and Files. When you upload a file it gets written to disk on the server. When I need to delete a folder and all of it's sub-folders, sub-folder files and the parent folders files, I select the folder and then click delete, which executes the controller action below.
UPDATE If I change any subsequent call to .ToList() it works.
[HttpPost]
public JsonResult DeleteFolder(int folderID)
{
var repo = new FileManagerRepository();
var folder = repo.GetFolder(folderID);
var subfolders = repo.GetSubFolders(folderID).ToList();
var files = repo.GetFiles(folderID).ToList();
// delete sub-folders
if (subfolders.Count() != 0)
{
foreach (var subfolder in subfolders)
{
// delete sub-folder files
var subfiles = repo.GetFiles(subfolder.folder_id).ToList();
if (subfiles.Count() != 0)
{
foreach (var file in subfiles)
{
repo.DeleteFile(file.file_id);
System.IO.File.Delete(Server.MapPath("/content/upload/" + file.file_name));
}
}
repo.DeleteFolder(subfolder.folder_id);
}
}
// delete files
if (files.Count() != 0)
{
foreach (var file in files)
{
repo.DeleteFile(file.file_id);
System.IO.File.Delete(Server.MapPath("/content/upload" + file.file_name));
}
}
// delete the folder
if (folder != null)
{
repo.DeleteFolder(folder.folder_id);
}
repo.Save();
return new JsonResult();
}
Now here is the FileManagerRepository
public class FileManagerRepository
{
private readonly iau_idahoEntities db = new iau_idahoEntities();
public IQueryable<folders> GetParentFolders()
{
return db.folders.Where(f => f.parant_folder_id == 0);
}
public IQueryable<folders> GetSubFolders()
{
return db.folders.Where(f => f.parant_folder_id != 0);
}
public IQueryable<folders> GetSubFolders(int folder_id)
{
return db.folders.Where(f => f.parant_folder_id != 0 && f.parant_folder_id == folder_id);
}
public IQueryable<Files> GetFiles(int id)
{
return db.Files.Where(f => f.folder_id == id);
}
public Files GetFile(int id)
{
return db.Files.SingleOrDefault(f => f.file_id == id);
}
public void UpdateDownloadCount(int id)
{
var file = GetFile(id);
file.downloaded += 1;
}
public void AddFolder(int parentFolderID, string folderName)
{
var folder = new folders { create_date = DateTime.Now, parant_folder_id = parentFolderID, folder_name = folderName };
db.folders.AddObject(folder);
}
public void DeleteFolder(int folder_id)
{
var folder = db.folders.SingleOrDefault(f => f.folder_id == folder_id);
db.folders.DeleteObject(folder);
}
public void Save()
{
db.SaveChanges();
}
public void AddFile(int folder_id,string filename, string description)
{
var file = new Files {
folder_id = folder_id,
file_name = filename,
file_extension = filename.Substring(filename.Length - 3, 3),
description = description,
downloaded = 0,
physical_name = filename.Substring(0, filename.Length - 4),
upload_date = DateTime.Now
};
db.Files.AddObject(file);
}
internal void DeleteFile(int fileID)
{
var fileToDelete = db.Files.SingleOrDefault(file => file.file_id == fileID);
db.Files.DeleteObject(fileToDelete);
}
internal folders GetFolder(int folderID)
{
return db.folders.SingleOrDefault(folder => folder.folder_id == folderID);
}
}
The problem is I keep getting the following EF Exception: There is already an open DataReader associated with this Command which must be closed first
I've tried to add MultipleActiveResultSets = true, to my connection string in the web.config, but I still get the exception. I know why this exception is being thrown, but I don't know how to do what I need to and prevent it from throwing an exception.
PLEASE HELP!!!
Upvotes: 0
Views: 242
Reputation: 7062
If I change all subsequent calls to the repository to ToList(), all works like it should.
var folder = repo.GetFolder(folderID);
var subfolders = repo.GetSubFolders(folderID).ToList();
var files = repo.GetFiles(folderID).ToList();
// delete sub-folders
if (subfolders.Count() != 0)
{
foreach (var subfolder in subfolders)
{
// delete sub-folder files
var subfiles = repo.GetFiles(subfolder.folder_id).ToList();
Upvotes: 0
Reputation: 13640
Change the var subfolders = repo.GetSubFolders(folderID);
line to var subfolders = repo.GetSubFolders(folderID).ToList();
Upvotes: 1