@@ -254,60 +254,56 @@ namespace Eg
254
254
<para >
255
255
Persistent entities don't necessarily have to be represented as POCO classes
256
256
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.
259
259
</para >
260
260
261
261
<para >
262
- The following examples demonstrates the representation using < literal >Dictionaries</ literal > .
262
+ The following examples demonstrates the dynamic model feature .
263
263
First, in the mapping file, an <literal >entity-name</literal > has to be declared
264
264
instead of a class name:
265
265
</para >
266
-
267
- <programlisting ><![CDATA[ <hibernate-mapping>
268
266
267
+ <programlisting ><![CDATA[ <hibernate-mapping>
269
268
<class entity-name="Customer">
270
-
271
- <id name="id"
269
+ <id name="Id"
272
270
type="long"
273
271
column="ID">
274
272
<generator class="sequence"/>
275
273
</id>
276
274
277
- <property name="name "
275
+ <property name="Name "
278
276
column="NAME"
279
277
type="string"/>
280
278
281
- <property name="address "
279
+ <property name="Address "
282
280
column="ADDRESS"
283
281
type="string"/>
284
282
285
- <many-to-one name="organization "
283
+ <many-to-one name="Organization "
286
284
column="ORGANIZATION_ID"
287
285
class="Organization"/>
288
286
289
- <bag name="orders "
287
+ <bag name="Orders "
290
288
inverse="true"
291
289
lazy="false"
292
290
cascade="all">
293
291
<key column="CUSTOMER_ID"/>
294
292
<one-to-many class="Order"/>
295
293
</bag>
296
-
297
294
</class>
298
-
299
295
</hibernate-mapping>]]> </programlisting >
300
-
296
+
301
297
<para >
302
298
Note that even though associations are declared using target class names,
303
299
the target type of an associations may also be a dynamic entity instead
304
300
of a POCO.
305
301
</para >
306
-
302
+
307
303
<para >
308
304
At runtime we can work with <literal >Dictionaries</literal >:
309
305
</para >
310
-
306
+
311
307
<programlisting ><![CDATA[ using(ISession s = OpenSession())
312
308
using(ITransaction tx = s.BeginTransaction())
313
309
{
@@ -328,7 +324,32 @@ using(ITransaction tx = s.BeginTransaction())
328
324
329
325
tx.Commit();
330
326
}]]> </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
+
332
353
<para >
333
354
The advantages of a dynamic mapping are quick turnaround time for prototyping
334
355
without the need for entity class implementation. However, you lose compile-time
@@ -338,8 +359,9 @@ using(ITransaction tx = s.BeginTransaction())
338
359
</para >
339
360
340
361
<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 >.
343
365
</para >
344
366
345
367
<programlisting ><![CDATA[ using(ISession s = OpenSession())
@@ -350,8 +372,23 @@ using(ITransaction tx = s.BeginTransaction())
350
372
.List<IDictionary<string, object>>();
351
373
...
352
374
}]]> </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
+
353
390
</sect1 >
354
-
391
+
355
392
<sect1 id =" persistent-classes-tuplizers" revision =" 1" >
356
393
<title >Tuplizers</title >
357
394
@@ -371,9 +408,9 @@ using(ITransaction tx = s.BeginTransaction())
371
408
</para >
372
409
373
410
<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
377
414
than the one used by default. Both would be achieved by defining a custom tuplizer
378
415
implementation. Tuplizers definitions are attached to the entity or component mapping they
379
416
are meant to manage. Going back to the example of our customer entity:
0 commit comments