Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository pattern implementation with data model in a tree structure

I have two data collections in two different models that implement a repository interface. One of them is in a flat list which fits great with the Repository model. The other data model is formatted in a a tree structure and the implementation of the repository interface I built looks very shady. I could try to flatten the second data model and just use references to parents but currently the application has some great benefits from being able to get the data as a tree structure.

What I'd like to know if is someone has any experience of implementing a repository pattern with a tree structured data model. Currently in my Get(Func<T, bool> predicate) method I flatten the list with a recursive method and return the object with a LINQ query but I feel like this implementation is a bit to costly.

Any tips about how to implement this would be appreciated.

Here's the implementation of the get by predicate method if that helps to illustrate the sillines of the implementation.

protected virtual IEnumerable<T> Get(Func<T, bool> predicate)
{
    var objects = GetAll<T>();
    return objects.Where(predicate);
}

EDIT: some more code

private IEnumerable<TreeData> GetRecursiveObjects(TreeData object)
    {
        var allChildren = new List<TreeData>();
        allChildren.AddRange(object.Children);

        foreach (var child in object.Children)
        {
            allChildren.AddRange(GetRecursiveObjects(child).ToArray());
        }
        return allChildren;
    }

    protected virtual IEnumerable<T> GetAll<T>()
    {
        var objects = new List<T>();
        objects.AddRange(Objects);
        foreach (var object in Objects)
        {
            objects.AddRange(GetRecursiveObjects(object));
        }
        return objects.OfType<T>();
    }

Second edit:

I'm also a bit confused about what a good strategy for adding elements to the repository would be. Should I handle the adding to children of the parent element in the using code or should the repository take both the element and a referens to it's parent and handle the whole add operation?

tl;dr

Is it insane to try to implement a repository interface with data in a tree structure?

like image 421
Moriya Avatar asked Dec 19 '12 16:12

Moriya


1 Answers

You could write a method that walks the tree and returns an IEnumerable<T> using an iterator block ( yield return ).

Then your wouldn't have to create a "flat" collection of the contents of your tree and you could just use LINQ to Objects to apply your predicate:

protected virtual IEnumerable<T> Get(Func<T, bool> predicate)
{
  return WalkAll().Where( predicate );
}

In fact, the LINQ query wouldn't even be evaluated until the client code enumerates it.

like image 50
Nick Butler Avatar answered Nov 09 '22 23:11

Nick Butler