2

I have a complex tree structure which I'm trying to create using code-first approach. The main idea is a class with a collection of children. Each child may by either the same type of the class itself (Folder) or some other class (File). This can be achieved in a programming language by the 2 classes deriving from a same basic interface. This this how I would prefer to represent my classes:

public interface IBasicTreeItem
{
    string DisplayName { get; }
}

public class Folder : IBasicTreeItem
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
    // This collection should be able to hold both Folder and File types
    public virtual ICollection<IBasicTreeItem> Children { get; set; }

    // Following 2 properties represent the parent folder
    // The file may not have a parent - in this case, it will be positioned in the root
    public int? FolderId { get; set; }
    public Folder ParentFolder { get; set; }
}

public class File : IBasicTreeItem
{
    public int Id { get; set; }
    public string DisplayName { get; set; }

    // Following 2 properties represent the parent folder
    // The file may not have a parent - in this case, it will be positioned in the root
    public int? FolderId { get; set; }
    public Folder ParentFolder { get; set; }
}

The problem is that this is not applicable in databases, at least not in this straightforward way, and that's where I need some help to figure out how to build my classes correctly.

A little something else I've tried is creating the database first and generate C# objects from it (File table had foreign-key to the Folder table, and so did the Folder table to itself) - it resulted in some errors, but I could see the basic idea it suggested - two collections in the Folder class, one for each son-type it can hold (which is not the solution I was hoping for since I would have to implement some kind of a middle collection which will have to unite both of the collections).

1 Answer 1

1

You can separate files and folders of Folder into two different collections - two tables, and implement some not mapped property of Folder class to return your files and folders casted to IBasicTreeItem

public interface IBasicTreeItem
{
    int Id { get; set; }
    string DisplayName { get; set; }
    int? FolderId { get; set; }        
}

public class BasicTreeItem : IBasicTreeItem 
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
    public int? FolderId { get; set; }        
}

public class Folder : BasicTreeItem
{   
    public Folder ParentFolder { get; set; } 
    public virtual ICollection<Folder> Folders { get; set; }
    public virtual ICollection<File> Files { get; set; }

    [NotMapped]
    public ICollection<IBasicTreeItem> Content { get {
       return Files.Concat(Folders).Cast<IBasicTreeItem>();
    } }
}

public class File : BasicTreeItem
{
    public Folder ParentFolder { get; set; }
}
Sign up to request clarification or add additional context in comments.

Comments

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.