This is my model:
- Business - BusinesType - FK - Categories (*) - FK - Branch (*) - BranchType - FK - Address - Phone (*) - CustomFields (*) - OpeningTimes (*) - WorkingPeriods (*) - .....
Now I have a controller-action that accepts a form that consists of the whole bunch of data as a single
Business entity with all its properties and collections set fine.
Now I have to walk thru all the properties and collections recursively, and compare with the database graph; if they don't exist, add them, if they do walk thru all properties again and perform the same to a deeper level until no navigation properties are left over. Since I have many more properties and descendants than mentioned in the previous example, it's just inside to walk thru them manually.
Thanks to this answer I found GraphDiff which offered a brilliant solution to the situation.
Here's an update query I'm calling:
Context.UpdateGraph(business, bus => bus .AssociatedEntity(bu => bu.BusinessType) .AssociatedCollection(bu => bu.Categories) .OwnedCollection(bu => bu.Branches, branch => branch .AssociatedEntity(b => b.BranchType) .OwnedEntity(b => b.Address) .OwnedCollection(b => b.Phones) .OwnedCollection(b => b.CustomFields) .OwnedCollection(b => b.OpeningTimes, openingTimes => openingTimes .OwnedCollection(b => b.WorkingPeriods) ) ) );
It throws this exception:
System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN' to type 'System.Linq.Expressions.MemberExpression'.
I tried debugging the source code, but I'm not an expert with Expression Trees, the problem occurs when the internal
Include call (to include object graph to load store object) tries to attach
WorkingPeriods, looks like it's not ready to take that deepness level of recursion. I messed around with it a bit, but I'm sure someone with extensive knowledge in expression trees will be able to solve this easily. Any suggestions will be appreciated on that to.
Here's what the include path expression is supposed to be generated like:
.Include(b => b.Branches.Select(br => br.OpeningTimes.Select(ot => ot.WorkingPeriods)));
Essentially, the exception is thrown because the recursive call returns the inner include as a method call, without processing it and returning the collection property it's meant to expose.
sorry it took me a while to get back to you.
I'ts 3am and I've had a fair bit of wine but the problem is fixed :) If you get the latest version of code @ https://github.com/refactorthis/GraphDiff it should work fine.
I'll update the new nuget package (RefactorThis.GraphDiff) soon.