Search code examples
nhibernatenhibernate-mapping

Mapping <set>+<element> to table with a surrogate id in NHibernate


I have the following C# class (simplified):

class Entity {
    Guid Id { get; set;}
    ISet<Uri> Urls { get; set; }
}

I want to map it to the following table structure:

TABLE Entity (
   Id uniqueidentifier PRIMARY KEY       
)

TABLE EntityUrls (
   Id uniqueidentifier PRIMARY KEY,
   EntityId uniqueidentifier FOREIGN KEY REFERENCES(Entity.Id),
   Uri varchar(250)
)

I can mostly map it using <set>, something like

<set name="Urls" table="EntityUrls">
  <key column="EntityId"/>
  <element column="Uri" type="..."/>
</set>

But how do I map the EntityUrls.Id column (at least generate Guid on INSERT)?
Or is it normally recommended to use composite PK in this case?


Solution

  • You can give it a try by creating a custom user type implementing ICompositeUserType:

    <set name="Urls" table="EntityUrls">
      <key column="EntityId"/>
    
      <element type="UserTypes.UriCompositeUserType">
        <column name="Id" />
        <column name="Uri" />
      </element>
    </set>
    

    Here is what NHibernate says about ICompositeUserType:

    A UserType that may be dereferenced in a query. This interface allows a custom type to define "properties". These need not necessarily correspond to physical .NET style properties. A ICompositeUserType may be used in almost every way that a component may be used. It may even contain many-to-one associations. Implementors must be immutable and must declare a public default constructor. Unlike UserType, cacheability does not depend upon serializability. Instead, Assemble() and Disassemble() provide conversion to/from a cacheable representation.