- changed title to Add recursive UpdateWithChildren and GetWithChildren variants (UpdateWithDescendants, GetWithDescendants?)
- edited description
Add recursive UpdateWithChildren and GetWithChildren variants (UpdateWithDescendants, GetWithDescendants?)
I expected UpdateWithChildren to also update children's children (and so on). I can see why not having that as the default behaviour is safer, and the name does include the word children and not descendants, which I suppose should be understood as only one layer down. However, a recursive version would be useful :)
Similarly, a GetWithDescendants recursive variant of GetWithChildren would be useful as well.
Comments (12)
-
reporter -
This is something definitely in the TODO list and it's perfectly doable, the main issue found here are loops and inverse relationships. How would you expect it to work with circular references?
On the other hand, inverse relationships may force you to load the entire database to memory when performing recursive operations. Maybe we could add another parameter ('IgnoreRecursiveRead' and 'IgnoreRecursiveWrite'?) like the 'ReadOnly' property to avoid this kind of issues.
If anyone comes with a better idea I'm open to suggestions.
Thanks for your feedback again.
-
reporter I'll most likely be needing to implement something like this myself, so if I do I'll do it on a Fork and PR it. I hadn't thought of the inverse relationships (I don't know my way around those yet) but I thought of getting around the other issues (recursion and depth) as follows: -(data size): Have a depth limit parameter on the GetWithDescendants call, and only keep fetching data down to that level -(loops) Internally call a version that takes a HashSet parameter and adds objects to the set as it goes. If the object the method is being called on is already in the hashset it early outs.
Would the HashSet check sort out the inverse relationship issue as well?
-
Yes, the HashSet solves the integral reference issue and loops to some degree. Let me explain the inverse relationship issue with an example:
Imagine a tree model like this:
Country -> Province -> City -> Street
Where all relationships are a 1:N relationship with an inverse property.
Calling GetChildren on a city to load the streets would also load it's province and will recursively the country too. Then, all the provinces of that country will be loaded and then all the cities of all the provinces and then all the streets of all the cities.
I'd solve this problem adding a parameter to the relationship attribute to avoid some of them being loaded recursively.
I'm going to create a branch with some test cases to see how it goes.
-
Already implemented recursive read operations, all tests passing so far. You can take a look at how it goes at the development branch. It seems to works pretty well if you ask me. Going for the write operations. It may take a while.
-
reporter That's great :) I started working on it my side over the weekend as well, but I realized my understanding of child/parent was incorrect which set me back a bit.
-
I don't think that 'UpdateWithChildren' makes sense being recursive. I think it makes much more sense creating 'insert' and 'delete' recursive methods, but updating recursively would be the same that 'InsertOrReplace' and the latter seems clearer. Any thoughts?
-
reporter My current use-case definitely leans more towards recursive insert (setting up some default data in the database, with current relationships up to 4 objects deep). Recursive update would probably be used far less frequently (in most cases a user would be making changes to a single object and maybe children one level down, and can immediately update just those), so it's probably less necessary.
-
InsertWithChildren
andInsertOrReplaceWithChildren
is now implemented and the tests are passing. Take into account that the API is not released yet and may change and the test suite or documentation is not complete yet. Take a look at the tests for examples on how to use it. -
InsertAllWithChildren
,InsertOrReplaceAllWithChildren
,Delete
andDeleteAll
methods have been created for recursive operations. The created test suite is passing. I'm going to add documentation for all this and it's going to the master branch in a few days. -
- changed status to resolved
Code and documentation already merged into master branch. Enjoy!
-
reporter Works a treat, thanks. Building up template data in code is an absolute pleasure now, as is reading data needed for particular areas.
- Log in to comment