I'm using NHibernate to persist my Item
class to a SQL database. The Item
class has a property Item.Tags
of type ICollection<Tag>
which I am mapping using the following NHibernate configation.
<set name="Tags" table="TagLinks" cascade="all" lazy ="false">
<key column="ItemId" />
<many-to-many class="Tag" column="TagID" />
</set>
Also here's my mapping for my Tag class, which simply has an int ID and a string name.
<class name="RCL.Tag" table="Tags" lazy="false" >
<id name ="TagID" column="TagID" >
<generator class="native"/>
</id>
<property name="Name" not-null="true"/>
</class>
This all works fine, yet it allows duplicate tags to be created with the same name. Thus the code below will create three separate "foo" entries in the Tags table all with separate IDs.
myItem1.Tags.Add(new Tag("Foo"));
myItem2.Tags.Add(new Tag("Foo"));
myItem3.Tags.Add(new Tag("Foo"));
This is obviously not how I want this to work. I could add a unique constraint to the Tags.Name column, but then the code above would only thrown an exception.
On the object model side I want to be able to simply add and remove tags from an Item
by editing a collection of Tag
or String
. However, when my items are persisted to the database it should figure out what new tags need to be created and when it should be mapping to existing entries in the Tags table.
I've also considered changing this to a value based one-to-many relationship where Item.Tags
would simply be a IList<String>
and would map to a single Tags table with entries for every individual tag on every Item
. This would work as well, but I think I would prefer the first, as it would make finding items with a specific tag more efficient. I'm pretty new to relational databases as well. So I'm not even sure if this should be a concern.