@@ -467,6 +467,119 @@ IList<Cat> oldCats =
467467 .ToList();]]> </programlisting >
468468 </sect1 >
469469
470+ <sect1 id =" querylinq-modifying" >
471+ <title >Modifying entities inside the database</title >
472+
473+ <para >
474+ Beginning with NHibernate 5.0, Linq queries can be used for inserting, updating or deleting entities.
475+ The query defines the data to delete, update or insert, and then <literal >Delete</literal >,
476+ <literal >Update</literal >, <literal >UpdateBuilder</literal >, <literal >InsertInto</literal > and
477+ <literal >InsertBuilder</literal > queryable extension methods allow to delete it,
478+ or instruct in which way it should be updated or inserted. Those queries happen entirely inside the
479+ database, without extracting corresponding entities out of the database.
480+ </para >
481+ <para >
482+ These operations are a Linq implementation of <xref linkend =" batch-direct" />, with the same abilities
483+ and limitations.
484+ </para >
485+
486+ <sect2 id =" querylinq-modifying-insert" >
487+ <title >Inserting new entities</title >
488+ <para >
489+ <literal >InsertInto</literal > and <literal >InsertBuilder</literal > method extensions expect a NHibernate
490+ queryable defining the data source of the insert. This data can be entities or a projection. Then they
491+ allow specifying the target entity type to insert, and how to convert source data to those target
492+ entities. Three forms of target specification exist.
493+ </para >
494+ <para >
495+ Using projection to target entity:
496+ </para >
497+ <programlisting ><![CDATA[ session.Query<Cat>()
498+ .Where(c => c.BodyWeight > 20)
499+ .InsertInto(c => new Dog { Name = c.Name + "dog", BodyWeight = c.BodyWeight });]]> </programlisting >
500+ <para >
501+ Projections can be done with an anonymous object too, but it requires supplying explicitly the target
502+ type, which in turn requires re-specifying the source type:
503+ </para >
504+ <programlisting ><![CDATA[ session.Query<Cat>()
505+ .Where(c => c.BodyWeight > 20)
506+ .InsertInto<Cat, Dog>(c => new { Name = c.Name + "dog", BodyWeight = c.BodyWeight });]]> </programlisting >
507+ <para >
508+ Or using assignments:
509+ </para >
510+ <programlisting ><![CDATA[ session.Query<Cat>()
511+ .Where(c => c.BodyWeight > 20)
512+ .InsertBuilder()
513+ .Into<Dog>()
514+ .Value(d => d.Name, c => c.Name + "dog")
515+ .Value(d => d.BodyWeight, c => c.BodyWeight)
516+ .Insert();]]> </programlisting >
517+ <para >
518+ In all cases, unspecified properties are not included in the resulting SQL insert.
519+ <link linkend =" mapping-declaration-version" ><literal >version</literal ></link > and
520+ <link linkend =" mapping-declaration-timestamp" ><literal >timestamp</literal ></link > properties are
521+ exceptions. If not specified, they are inserted with their <literal >seed</literal > value.
522+ </para >
523+ <para >
524+ For more information on <literal >Insert</literal > limitations, please refer to
525+ <xref linkend =" batch-direct" />.
526+ </para >
527+ </sect2 >
528+
529+ <sect2 id =" querylinq-modifying-update" >
530+ <title >Updating entities</title >
531+ <para >
532+ <literal >Update</literal > and <literal >UpdateBuilder</literal > method extensions expect a NHibernate
533+ queryable defining the entities to update. Then they allow specifying which properties should be
534+ updated with which values. As for insertion, three forms of target specification exist.
535+ </para >
536+ <para >
537+ Using projection to updated entity:
538+ </para >
539+ <programlisting ><![CDATA[ session.Query<Cat>()
540+ .Where(c => c.BodyWeight > 20)
541+ .Update(c => new Cat { BodyWeight = c.BodyWeight / 2 });]]> </programlisting >
542+ <para >
543+ Projections can be done with an anonymous object too:
544+ </para >
545+ <programlisting ><![CDATA[ session.Query<Cat>()
546+ .Where(c => c.BodyWeight > 20)
547+ .Update(c => new { BodyWeight = c.BodyWeight / 2 });]]> </programlisting >
548+ <para >
549+ Or using assignments:
550+ </para >
551+ <programlisting ><![CDATA[ session.Query<Cat>()
552+ .Where(c => c.BodyWeight > 20)
553+ .UpdateBuilder()
554+ .Set(c => c.BodyWeight, c => c.BodyWeight / 2)
555+ .Update();]]> </programlisting >
556+ <para >
557+ In all cases, unspecified properties are not included in the resulting SQL update. This could
558+ be changed for <link linkend =" mapping-declaration-version" ><literal >version</literal ></link > and
559+ <link linkend =" mapping-declaration-timestamp" ><literal >timestamp</literal ></link > properties:
560+ using <literal >UpdateVersioned</literal > instead of <literal >Update</literal > allows incrementing
561+ the version. Custom version types (<literal >NHibernate.Usertype.IUserVersionType</literal >) are
562+ not supported.
563+ </para >
564+ <para >
565+ When using projection to updated entity, please note that the constructed entity must have the
566+ exact same type than the underlying queryable source type. Attempting to project to any other class
567+ (anonymous projections excepted) will fail.
568+ </para >
569+ </sect2 >
570+
571+ <sect2 id =" querylinq-modifying-delete" >
572+ <title >Deleting entities</title >
573+ <para >
574+ <literal >Delete</literal > method extension expects a queryable defining the entities to delete.
575+ It immediately deletes them.
576+ </para >
577+ <programlisting ><![CDATA[ session.Query<Cat>()
578+ .Where(c => c.BodyWeight > 20)
579+ .Delete();]]> </programlisting >
580+ </sect2 >
581+ </sect1 >
582+
470583 <sect1 id =" querylinq-querycache" >
471584 <title >Query cache</title >
472585
0 commit comments