0

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!!!

2 Answers 2

1

Change the var subfolders = repo.GetSubFolders(folderID); line to var subfolders = repo.GetSubFolders(folderID).ToList();

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for pointing me in the right direction. It's been a while since I've done any Entity Framework.
0

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();

1 Comment

Yes, to all results of the queries which you iterate through.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.