Grace Atwood
Grace Atwood

Reputation: 172

C# NHibernate - Remove all references to object on delete

I have two objects. One, the parent, references a Locale. This locale is from a list of locales. When that locale is deleted, I want it to clean up any references to itself from all referencing types (setting the relevant value to null).

Right now, I have a system that walks across all entities that NHibernate is mapping and, by using their class metadata, determines which types reference the locale type. Then, I build a query (using ICriteria) for that referencing type where the property of type Locale equals the locale's Id that I'm trying to delete. Any objects that come back, I set that property to null and then update them.

Question: Is there a better way - hopefully using something built into NHibernate - to instruct an object to remove all references to itself on delete?

Objects:

public class Parent
{
    public virtual Guid Id { get; set; }
    public virtual Locale Loc { get; set; }
}

public class Locale
{
    public virtual Guid Id { get; set; }
}

Mappings:

public class ParentMapping : ClassMap<Parent>
{
    Id(x => x.Id).GeneratedBy.Guid();

    References(x => x.Loc).Nullable();
}

public class LocaleMapping : ClassMap<Locale>
{
    Id(x => x.Id).GeneratedBy.Guid();
}

Upvotes: 2

Views: 1117

Answers (1)

Grace Atwood
Grace Atwood

Reputation: 172

As requested, here's how I wound up dealing with this problem. I actually used a suggestion originally given by @Fran to come up with a solution.

Solution

This solution is very specific to my type of application and involves using a number of parts of the application working together to achieve my desired result. Specifically, my application is a RESTful web service, powered by WCF, JSON.NET, and NHibernate.

First, I added a reference to all parents in the locale and used a HasMany mapping, so that the locale knew all of the parents that reference it:

public virtual IList<Parent> Parents { get; set; }

and

HasMany(x => x.Parents);

It's also important to point out here that I use lazy loading throughout the application.

While this allowed me to easily delete the locale by using the proper cascade behaviors, this posed a problem in loading/GET scenarios in that when I passed the locale into JSON.NET (on its way out the door to the client), JSON.NET would walk the Parents collection, and serialize the whole thing. Obviously, this is undesired as we're feeding the client much more than they asked for. This is the problem I alluded to in my comment in the OP.

As @Fran mentioned, I could use projections; however, all of my reference lists are accessed through a common endpoint in order to abstract their CRUD operations and reduce the amount of repeated code: all of my reference lists implement an abstract class called ReferenceListBase. Anyways, I wanted a solution in which the implementing class itself was able to decide how much of it should be sent to the client (serialized).

My solution was to put a [JsonIgnore] attribute on the Parents collection, which, in conjuction with lazy loading, means that JSON.NET never looks at the property and therefore, the relationship never gets loaded.

This solution has always kind of felt like a hack, but it has achieved all of the results I want and made adding new reference lists very easy. I hope this helps you; if it doesn't, post a new question, link it here, and I'll try to help you out. :)

Upvotes: 1

Related Questions