Smooth circular support pain

I have 2 entities in my domain A and B

Object A has property B Object B has property of list

when i hit my db, from B, it returns a list of As, but each A has a B, which in turn has a list of As. again and again.

clearly a lazy loading problem. Spoof loading is enabled, but my problem is that this is a WCF service, I need to convert all my domain objects to dto objects in order to send the wire, and when I do that, do this: pseudocode

ADTO adto Transform(ADomain a)
{
   adto.name = a.name;
   adto.surname = a.surname;
   adto.B = Transform(a.B);
}

BDTO bdto Transform(BDomain b)
{
   bdto.bob = b.bob;
   foreach (A a in b.As)
   {
       bdto.bs.add(Transform(a));
   }
}

      

since I can only make my collection fetch one layer deep.

Map B:

HasMany(x => x.As)
            .Cascade.AllDeleteOrphan()
            .Fetch.Select()
            .Inverse().KeyColumn("AId");

      

Display:

 References(x => x.B).Column("AId");

      

+3


source to share


1 answer


Well, to pass a circular reference to WCF, you have to set up a Parent DTO (B) with a IsReference

DataContractAttribute.IsReference Property (or here Circular Reference Issue ).

Use the IsReference property to instruct the DataContractSerializer to insert XML constructs that preserve information about an object. [DataContract(Namespace = "http://domain.../", IsReference=true)]

public class BDTO ...

To give you an answer:

... since I can only fetch from the collection with one layer.

NHibernate will have no problem with circular references. And even more than that, you can easily get all the data by executing only 2 SQL queries. Customize the display:



HasMany(x => x.As)
  .Cascade.AllDeleteOrphan()
  .BatchSize(25)
  //.Not.LazyLoad()
  .Inverse()
  .KeyColumn("AId");

      

NOTE. Not.LazyLoad only makes sense if object A is almost always needed for B. When using "lazy" mode, you must keep the session open while processing the entire WCF service

The BatchSize parameter will optimize the object load lists B. More details here: http://ayende.com/blog/3943/nhibernate-mapping-set

The NHibernate session will execute two queries: 1) Select B

and 2) Select A for all B

and materialize the results into full instances of A and B, with references in both directions fully populated. The NHibernate session will serve you fully loaded instances. Even calls Get<A>(id)

and Get<B>(id)

will fetch objects from the session

The next steps are up to you, you can use DTO objects, display tools to transform them ...

+1


source







All Articles