NHibernate Mapping - <dynamic-component/>

Like the <component/> mapping, <dynamic-component/> allows us to treat parts of the entity table in a special way. In this case, it allow us to push properties from the mapping into a dictionary, instead of having to have the entity have properties for it.

This is very useful when we need to build dynamically extended entities, where the client can add columns on the fly.

Let us take this entity as an example:

image

And this table:

image

Where we want to have the SSN accessible from our entity, but without modifying its structure. We can do this using <dynamic-component/>:

<class name="Person"
		table="People">

	<id name="Id">
		<generator class="identity"/>
	</id>
	<property name="Name" />

	<dynamic-component name="Attributes">
		<property name="SSN"
			type="System.String"/>
	</dynamic-component>
</class>

And the query just treat this as yet another column in the table:

image

Print | posted on Saturday, April 11, 2009 7:23 AM

Feedback


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/11/2009 1:39 PM Tobin Harris

That's a great feature, I didn't even know it was there.

So I guess this lets you do:

var person = _session.Load(1);
Assert.AreEqual( "123", person.Attributes["SSN"] );

I assume that mapping properties into a dictionary is the primary use case -- very handy for multi-tenanted apps -- are their any other things you've used it for?


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/11/2009 1:45 PM Ayende Rahien

Tobin,
Yes, that is what it is for.
It is useful in any case where you need to dynamically extend your entities.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/11/2009 7:40 PM justin

I guess my question would be _how_ do you dynamically extend the entity? Putting some data in the xml document about your mapping doesn't seem very dynamic to me.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/11/2009 9:06 PM Ayende Rahien

Justin,
You usually would do this by manipulating the mapping problematically.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/12/2009 5:16 AM Mike

Putting some data in the xml document about your mapping doesn't seem very dynamic to me.

nor does adding a column to the database. Is there anyway you could show an example that uses a property bag in both the database and object model?


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/12/2009 5:58 AM Ayende Rahien

Mike, you can create an Attributes table very easily, and map it using standard NH facilities.
That tend to be slower, however, because you need an additional select or a join.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/13/2009 10:12 AM meowth

Hrr. I had to use Boo compiler to regenerate entities on-the-fly when adding fields instead of simply using dynamic component..

Thank you for this set of lectures about NHibernate features, Ayende.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 2:39 PM CAM

Excellent stuff, a question on using an Attributes table comment. How would you make the Attributes property a simple dictionary?


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 2:41 PM Ayende Rahien

CAM,
Attributes is IDisctionary


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 3:57 PM CAM

Sorry Ayende, I was referring to Mike's comment. Could you show an example of how to map a property bag table (Name/Value Pair) in DB to an IDictionary Attributes property of a class?


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 4:28 PM Ayende Rahien

CAM,
Take a look at the {map/} element


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 4:51 PM CAM

Excellent Ayende thank you.


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 6:43 PM tolly

How can i solve this (see picture) problem with NHibernate? i have a superclass Question and a lot of subclasses, all with their own specific attributes. I don't want to create table for each class, because of perfomance. The solution is to make an QuestionDetail table with key, value columns where i can store names and values of all specific attributes from subclasses. How can i do it in NHibernate?
tweakers.net/.../full.jpg


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/15/2009 10:50 PM Ayende Rahien

Tolly,
Take a look at {map/}


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/16/2009 11:13 AM tolly

Thanks, Ayende, it works :-)
I have added IDictionary Properties to my Question class to map key-value pairs. My mapping looks like this:
{map name="Properties" table="QuestionDetails" }
{key column="QuestionID" /}
{index column="Name" type="String" /}
{element column="Value" type="String" /}
{/map}
How can i force NHibernate to use this mapping if I create new QuestionType (subclass) object? Now create a Question object as follows:
Question sbq = new Question();
sbq.attr1= "attr1value";
sbq.attr2= "attr2value";
sbq.Properties = new Dictionary();
sbq.Properties.Add( "attr3", "attr3" );
sbq.Properties.Add( "attr4", "attr4" );
And I'd like to have it so:
QuestionType2 sbq = new QuestionType2 ();
sbq.attr1= "attr1value";
sbq.attr2= "attr2value";
sbq.attr2= "attr3value";
sbq.attr2= "attr4value";
Should I use discriminator? Or ? If I use , than NHibernate just puts subclass attributes to the Question table, or in QuestionType2 table when using
Thanks in advance :)


Gravatar

# re: NHibernate Mapping - <dynamic-component/> 4/16/2009 11:20 AM Ayende Rahien

Anatoly,
Wait a few days, the post about {join/} will show up

Comments have been closed on this topic.