Difference between revisions of "NHibernate"

From no name for this wiki
Jump to: navigation, search
(Insert, Updates und Save())
(Insert)
Line 341: Line 341:
 
session.Close();
 
session.Close();
 
</source>
 
</source>
 +
 +
* None(): NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.
  
 
== resourcen ==
 
== resourcen ==
 
* http://nhforge.org/doc/nh/en/index.html
 
* http://nhforge.org/doc/nh/en/index.html

Revision as of 00:37, 30 October 2013

Konfigurationsdatei Sample

sqlserver sample

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">Server=(local);Database=nhibernate;Trusted_Connection=true;</property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

Mysql example

<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
  </configSections>
  <appSettings>
    <add key="loglevel" value="info"/>
    <add key="logimplementation" value="NLOG"/>
    <add key="exportdirectory" value="/tmp" />
  </appSettings>
  <connectionStrings>
    <add name="testmasterconnection"
         connectionString="server=localhost;user=root;pwd=dukannstmichmal;database=mydb;port=3306;"
         providerName="MySql.Data.MySqlClient" />
  </connectionStrings>

  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
      <property name="connection.connection_string_name">testmasterconnection</property>
      <property name="show_sql">true</property>
      <property name="hbm2ddl.keywords">none</property>
    </session-factory>
  </hibernate-configuration>

  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets>
      <target name="logfile" xsi:type="File" fileName="out.txt" />
      <target name="console" xsi:type="Console" />
    </targets>

    <rules>
      <logger name="*" minLevel="Info" writeTo="logfile" />
      <logger name="*" minLevel="Info" writeTo="console" />
      <logger name="TagsManagement" minLevel="Debug" writeTo="console" />
    </rules>

  </nlog>
</configuration>

many to many mapping

Mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="ConsoleApplication2"
                   namespace="ConsoleApplication2">

  <class name="MyItem">
    
    <id name="ID" generator="native"/>
    
    <property name="Name" />

    <!-- Many-to-many mapping: OrderItems -->
    <bag name="Tags" 
         table="MyItem_MyTag" 
         cascade="none" 
         lazy="true">
      <key column ="MyItemID" />
      <many-to-many class="MyTag" column="MyTagID" />
    </bag>
    
  </class>

</hibernate-mapping>

Klasse:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    public class MyItem
    {
        public virtual string Name { get; set; }
        public virtual int ID { get; set; }

        IList<MyTag> _tags = new List<MyTag>();
        public virtual IList<MyTag> Tags {
            get
            {
                return this._tags;
            }
            set
            {
                _tags = value;
            }
        }
    }
}

Konfiguration mit fluet configuration

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate.Cfg;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;

namespace ConsoleApplication2
{
    class Program
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {

                var sessionFactory = Fluently.Configure()
                                             .Database(
                                                    MsSqlConfiguration.MsSql2005
                                                                      .ConnectionString(
"Server=(local);Database=nhibernate;Trusted_Connection=true;")
                                                                      .ShowSql()
                                              )
                                             .Mappings(m => m
                                             .FluentMappings.AddFromAssemblyOf<Program>())
                                             .BuildSessionFactory();

                ISession session = sessionFactory.OpenSession();



                ...
                  
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }
        }
    }
}

using FluentNHibernate.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2.Mappings
{
    class MyItemMap : ClassMap<MyItem>
    {
        public MyItemMap()
        {
            Id(x => x.ID).GeneratedBy.Native();

            Map(x => x.Name);

            HasManyToMany(x => x.Tags)
                .Table("MyItem_MyTag")
                .ParentKeyColumn("MyItemID")
                .ChildKeyColumn("MyTagID")
                .Cascade.None().LazyLoad();

        }
    }
}

Wenn Fremdschlüssel kein Constraint aufweist:

 //Cache einschalten:
 Cache.ReadOnly().Region("Keep15Min");

 //Fremdschlüssel ohne Fremdschlüsselconstraint
 References(x => x.Verantwortlicher, "strVerantwortlicher").Nullable()
                .ForeignKey("FK_Vertrag_Verantwortlicher_Employee")
                .Index("IX_strVerantwortlicherId")
                .NotFound.Ignore()
                .Access.CamelCaseField(Prefix.Underscore);

Queries

OR, Criteria

var query = context.Session.CreateCriteria<Tag>();query.Add(Restrictions.Or(Restrictions.Where<Tag>(t => t.NameDe.IsLike(searchString)),Restrictions.Where<Tag>(t => t.NameEn.IsLike(searchString))));
              

return query.List<Tag>();

HQL, Latest related object

select item, tag
from MyItem item
    join item.Tags tag
where tag.Id = (                                    
    select  max(tag2.Id)  
    from MyItem item2
        join item2.Tags tag2
    where item2.Id = item.Id
    group by item2.Id     
)

OR, Query Over

using (DbContext context = new DbContext())
{

    Tag tag = null;

    return context.Session.QueryOver<Tag>()
        .Where(t => t.NameDe.IsLike(searchString) || t.NameEn.IsLike(searchString))
        .SelectList(
        list => list.Select(x => x.Id).WithAlias(() => tag.Id)
                    .Select(x => x.NameDe).WithAlias(() => tag.NameDe)
                    .Select(x => x.NameEn).WithAlias(() => tag.NameEn))
                .TransformUsing(Transformers.AliasToBean<Tag>()).List<Tag>();
}

Insert, Updates und Save()

Hier gibt es keine Änderung an der Datenbank:

ISession session = sessionFactory.OpenSession();
MyTag tag = session.Get<MyTag>(17);
tag.Name = "Furunkel"; //Wird nicht in DB übernommen.
session.Close();

Ohne Transaktion kein Update.


Änderung an der Datenbank ohne Save:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
MyTag tag = session.Get<MyTag>(17);
tag.Name = "Furunkel";
tx.Commit(); //Schreibt die Änderung in die DB.

Save:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
MyTag tag = new MyTag();
tag.Name = "test";
session.Save(tag); //Insert Statement wird hier zur DB ausgegeben. Id von db wird hier gelöst.
tx.Commit();

Save mit Update:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
MyTag tag = session.Get<MyTag>(17);
tag.Name = "Elefant";
session.Save(tag); //Da Transaktion vorhanden ist, wird hier kein Update SQL ausgegeben.
tx.Commit(); //Schreibt die Änderung in die DB.
              
session.Close();

Das macht gar nichts:

ISession session = sessionFactory.OpenSession();
MyTag tag = session.Get<MyTag>(17);
tag.Name = "Elefant";
session.Save(tag); //Das macht gar nichts, da keine Tx vorhanden ist.
              
session.Close();

Here is what each cascade option means:

none - do not do any cascades, let the users handles them by themselves. save-update - when the object is saved/updated, check the associations and save/update any object that require it (including save/update the associations in many-to-many scenario). delete - when the object is deleted, delete all the objects in the association. delete-orphan - when the object is deleted, delete all the objects in the association. In addition to that, when an object is removed from the association and not associated with another object (orphaned), also delete it. all - when an object is save/update/delete, check the associations and save/update/delete all the objects found. all-delete-orphan - when an object is save/update/delete, check the associations and save/update/delete all the objects found. In additional to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.

Cascading

Insert

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();

MyItem item = new MyItem { Name = "CascadeAllItem" };
MyTag tag = new MyTag { Name = "CascadeAllTag" };
item.Tags.Add(tag);

session.Save(item);

tx.Commit(); 
              
session.Close();
* None(): NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.

resourcen