Querying objects with cyclic references

Apr 2, 2009 at 4:29 PM
Hi,

First of all, thanks for the great toolkit. I've almost finished implementing Linq support for our in-house orm system. Linq makes querying the database almost too fun!

I however have a problem that has to do with our class library containing cyclic references. For example, we have classes Delivery and Contract:

public class Delivery : IBusinessObject
{
    public int Id {get; set;}
    public Contract Contract {get; set;}
}

public class Contract : IBusinessObject
{
    public int Id {get; set;}
    ...
}
    
When querying deliveries, the developer can choose to query the delivery table only. In that case, the Contract property will contain a  object that has only the Id property value set. The class is otherwise empty. The developer can also choose to query the deliveries and contracts related to that delivery. In that case a join will be done and the Contract object will be fully populated.

db.SetIncludes(DeliveryMember.Contract); // Call this to incude the Contract object
var results = from d in db.Deliveries
where d.Code.Contains("a")
select d;

The problem comes when I query the Contract objects and introduce a new property: a list of deliveries.

public class Contract : IBusinessObject
{
    public int Id {get; set;}
    public List<Delivery> {get; set;}
    ...
}

As with deliveries, the developer can still choose to query the contract table only. No problem. But: I would also like to have the option to query the contract object and do a join to delivery table to populate the Deliveries property. I would also like all Deliveries's Contract properties point to the same parent Contract object.

Is there a way I could make a delivery in the delivery list to point to its parent Contract?

Currently, if do the query and tell that I want to include Contract's Deliveries and Delivery's Contract I'll end up in an infinite loop since QueryMapping.GetMemberExpression keeps on calling itself. I can of course change it so that in this case Deliveries' Contracts would not be loaded (or populate them with the Id only), but I'd rather have them populated with the parent Contract.

Any ideas?
Coordinator
May 7, 2009 at 1:04 AM
First you have to make sure that the policy does not allow direct cycles or you'll get the same never ending loop trying to define the actual query.  Second, it would be possible to modify the materialization logic to assign back-pointer to the containing object. I'm not sure how to go about it yet, either.