@@ -254,60 +254,56 @@ namespace Eg
254254 <para >
255255 Persistent entities don't necessarily have to be represented as POCO classes
256256 at runtime. NHibernate also supports dynamic models
257- (using <literal >Dictionaries</literal >). With this approach, you don't
258- write persistent classes, only mapping files.
257+ (using <literal >Dictionaries</literal > or C# < literal >dynamic</ literal > ). With this approach,
258+ you don't write persistent classes, only mapping files.
259259 </para >
260260
261261 <para >
262- The following examples demonstrates the representation using < literal >Dictionaries</ literal > .
262+ The following examples demonstrates the dynamic model feature .
263263 First, in the mapping file, an <literal >entity-name</literal > has to be declared
264264 instead of a class name:
265265 </para >
266-
267- <programlisting ><![CDATA[ <hibernate-mapping>
268266
267+ <programlisting ><![CDATA[ <hibernate-mapping>
269268 <class entity-name="Customer">
270-
271- <id name="id"
269+ <id name="Id"
272270 type="long"
273271 column="ID">
274272 <generator class="sequence"/>
275273 </id>
276274
277- <property name="name "
275+ <property name="Name "
278276 column="NAME"
279277 type="string"/>
280278
281- <property name="address "
279+ <property name="Address "
282280 column="ADDRESS"
283281 type="string"/>
284282
285- <many-to-one name="organization "
283+ <many-to-one name="Organization "
286284 column="ORGANIZATION_ID"
287285 class="Organization"/>
288286
289- <bag name="orders "
287+ <bag name="Orders "
290288 inverse="true"
291289 lazy="false"
292290 cascade="all">
293291 <key column="CUSTOMER_ID"/>
294292 <one-to-many class="Order"/>
295293 </bag>
296-
297294 </class>
298-
299295</hibernate-mapping>]]> </programlisting >
300-
296+
301297 <para >
302298 Note that even though associations are declared using target class names,
303299 the target type of an associations may also be a dynamic entity instead
304300 of a POCO.
305301 </para >
306-
302+
307303 <para >
308304 At runtime we can work with <literal >Dictionaries</literal >:
309305 </para >
310-
306+
311307 <programlisting ><![CDATA[ using(ISession s = OpenSession())
312308using(ITransaction tx = s.BeginTransaction())
313309{
@@ -328,7 +324,32 @@ using(ITransaction tx = s.BeginTransaction())
328324
329325 tx.Commit();
330326}]]> </programlisting >
331-
327+
328+ <para >
329+ Or we can work with <literal >dynamic</literal >:
330+ </para >
331+
332+ <programlisting ><![CDATA[ using(var s = OpenSession())
333+ using(var tx = s.BeginTransaction())
334+ {
335+ // Create a customer
336+ dynamic frank = new ExpandoObject();
337+ frank.Name = "Frank";
338+
339+ // Create an organization
340+ dynamic foobar = new ExpandoObject();
341+ foobar.Name = "Foobar Inc.";
342+
343+ // Link both
344+ frank.Organization = foobar;
345+
346+ // Save both
347+ s.Save("Customer", frank);
348+ s.Save("Organization", foobar);
349+
350+ tx.Commit();
351+ }]]> </programlisting >
352+
332353 <para >
333354 The advantages of a dynamic mapping are quick turnaround time for prototyping
334355 without the need for entity class implementation. However, you lose compile-time
@@ -338,8 +359,9 @@ using(ITransaction tx = s.BeginTransaction())
338359 </para >
339360
340361 <para >
341- A loaded dynamic entity can be manipulated as an <literal >IDictionary</literal > or
342- <literal >IDictionary< string, object> </literal >.
362+ A loaded dynamic entity can be manipulated as an <literal >IDictionary</literal >,
363+ an <literal >IDictionary< string, object> </literal > or a C#
364+ <literal >dynamic</literal >.
343365 </para >
344366
345367 <programlisting ><![CDATA[ using(ISession s = OpenSession())
@@ -350,8 +372,23 @@ using(ITransaction tx = s.BeginTransaction())
350372 .List<IDictionary<string, object>>();
351373 ...
352374}]]> </programlisting >
375+
376+ <programlisting ><![CDATA[ using System.Linq.Dynamic.Core;
377+
378+ ...
379+
380+ using(ISession s = OpenSession())
381+ using(ITransaction tx = s.BeginTransaction())
382+ {
383+ var customers = s
384+ .Query<dynamic>("Customer")
385+ .OrderBy("Name")
386+ .ToList();
387+ ...
388+ }]]> </programlisting >
389+
353390 </sect1 >
354-
391+
355392 <sect1 id =" persistent-classes-tuplizers" revision =" 1" >
356393 <title >Tuplizers</title >
357394
@@ -371,9 +408,9 @@ using(ITransaction tx = s.BeginTransaction())
371408 </para >
372409
373410 <para >
374- Users may also plug in their own tuplizers. Perhaps you require that a <literal >IDictionary</literal >
375- implementation other than <literal >System.Collections.Generic.Dictionary < string, object > </literal >
376- is used while in the dynamic-map entity-mode; or perhaps you need to define a different proxy generation strategy
411+ Users may also plug in their own tuplizers. Perhaps you require that a <literal >IDictionary</literal > /
412+ <literal >DynamicObject </literal > implementation other than NHibernate own implementation is used while
413+ in the dynamic-map entity-mode; or perhaps you need to define a different proxy generation strategy
377414 than the one used by default. Both would be achieved by defining a custom tuplizer
378415 implementation. Tuplizers definitions are attached to the entity or component mapping they
379416 are meant to manage. Going back to the example of our customer entity:
0 commit comments