Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
562 views
in Technique[技术] by (71.8m points)

entity framework - Exception in Expression Trees

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

Here's the stacktrace of the error.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...