var blog = new ThoughtStream(me); RSS 2.0
 Monday, March 24, 2008

In WCF, when using NetDataContractSerializer to enable .NET Remoting, DataContract objects are still serialized. Only ServiceContract objects are marshaled ByRef. The same setup is possible in native .NET Remoting, as well. It seems more likely to happen in WCF, though. Based on my experience, Remoting is usually all MarshalByRef or all Serialized - but that's just my experience. Either way, if you are serializing your object model, you need to be careful.

Parent <-> Child Bidirection Relationships

If you have a Parent<->Child bidirectional relationship in your DataContract objects, when you send the DataContract objects across WCF, they will be serialized/deserialized and the resulting hierarchy of objects will be: Parent->Child->CopyOfParent. This causes problems when using NHibernate to auto save/load your object tree.

For example, this object hierarchy:

Parent
  |--Child
  |     |--Parent (reference to actual Parent)

Will end up looking like this, after being serialized / deserialized:

Parent
  |--Child
  |     |--CopyOfParent (new object, independent of actual Parent)

To fix this, you'll have to manually re-build your references, after the objects are deserialized:

foreach(Child child in parent.Children)
{
    child.Parent = parent;
}

If you don't rebuild the hierarchy references like this, NHibernate will not save or update your child objects correctly. You will either get "Transient Instance" exceptions or you will end up with orphaned children records because they will not have their parent id set correctly.

Here's an example of what one of my data access methods looks like, in an app that remotes the data access layers via WCF (and hides most of the NHibernate code in a base class):

public void Save(FooBar fooBar)
{
    try
    {
 
        foreach(Widget widget in fooBar.Widgets)
        {
            widget.FooBar = fooBar;
        }
 
        OpenSession();
        BeginTransaction();
        Session.SaveOrUpdate(fooBar);
        CommitTransaction();
    }
    catch
    {
        RollbackTransaction();
        throw;
    }
    finally
    {
        CloseSession();
    }
}

Extended Problem: Multi-Parented Children

Although I haven't run into this situation yet, I am assuming that the same problem will occur if you have multiple parents pointing to the same child. For example, if you have:

Parent
  |--Child1
  |     |--GrandChild1 (same reference as Child2's GrandChild)
  |--Child2
  |     |--GrandChild1 (same reference as Child1's GrandChild)

When you send this structure across WCF as a set of DataContract objects, I imagine that you will end up with this:

Parent
  |--Child1
  |     |--GrandChild1 (duplicate of Child2's GrandChild)
  |--Child2
  |     |--CopyOfGrandChild1 (duplicate of Child1's GrandChild)

If your intention is to have Child1 and Child2 reference the same record in the database, you will need to reconstruct the Child1 and Child2 references to GrandChild1, ensuring that both point to the same object. I can see the basic code as traversing the children and comparing each of the gradchildren's values, then picking one winner between the same values and resetting the references on the rest of them. Unfortunately, I think the solution for this scenario would likely be unique to each situation, due to the complexity of picking the correct reference.

Has anyone run into this situation? If so, how did you solve it?

Monday, March 24, 2008 2:01:16 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: .NET | NHibernate | WCF

Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<December 2008>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Derick Bailey
Sign In
Statistics
Total Posts: 91
This Year: 91
This Month: 0
This Week: 0
Comments: 40
Themes
Pick a theme:
All Content © 2008, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)