views:

914

answers:

2

I'm using Nhibernate and fluent nhibernate to create a mapping file for a domain object (though I don't care if an answer uses fluent nhibernate or xml hbm syntax). And I'm having trouble with figuring out how I specify that a set of columns representing a component within the domain object is unique.

Here's the domain object:

public class SpaceLocation
{
        public SpaceCoordinate Coordinates { get; set; }
        public SpaceObject AtLocation { get; set; }
}

and here is the component I'm having trouble with:

public struct SpaceCoordinate
{
        public int x { get; set; }
        public int y { get; set; }
        public int z { get; set; }
}

Don't worry about SpaceObject AtLocation for the purposes of this quesiton.

So I know how to make a component out of SpaceCoordinate, but I want to make it so that there cannot be duplicate inserts of the same set of Coordinates. In order to do this, I want to make the component as a whole unique.

To give you a sense of the direction I'm trying to go, I'll show you what I have for the mapping class:

public class SpaceLocationMap : ClassMapWithGenerator<SpaceLocation>
    {
        public SpaceLocationMap()
        {

            Component<SpaceCoordinate>(x => x.Coordinates, m => 
            {
                m.Map(x => x.x);
                m.Map(x => x.y);
                m.Map(x => x.z);
            });
        }
    }

The problem with this fluent NHibernate mapping is that it does not apply the unique constraint to the SpaceCoordinate's values collectively. Mind you I'm not trying to set each as unique individually, that would be too restrictive.

So how would you map with this with a hbm or fluent map file?

Any help would be greatly appreciated, Thanks for reading!!

A: 

I believe the answer is something like this:

<class name="SpaceLocation" table="SpaceLocation">
    <property name="AtLocation" type="SpaceObject"/>
    <component name="Coordinates" class="SpaceCoordinate" unique="true">
        <property name="x"/>
        <property name="y"/>
        <property name="z"/>
    </component>
</class>

But I haven't checked yet. Now how to do it in fluent nhibernate?

Mark Rogers
+2  A: 

m4bwav was correct with the hbm mapping; however, Fluent NHibernate didn't have support for this at the time you wrote your question. I've just committed a fix that adds a Unique method to the component mapping.

Component<SpaceCoordinate>(x => x.Coordinates, m => 
{
  m.Map(x => x.x);
  m.Map(x => x.y);
  m.Map(x => x.z);
}).Unique();

So you'll need to update your copy of Fluent NHibernate. If you're unable to do this for some reason, you could use the SetAttribute method to hack it.

Component<SpaceCoordinate>(x => x.Coordinates, m => 
{
  m.Map(x => x.x);
  m.Map(x => x.y);
  m.Map(x => x.z);
}).SetAttribute("unique", "true");
James Gregory