Difference between revisions of "NHibernate"

From no name for this wiki
Jump to: navigation, search
(Queries)
(Konfiguration mit fluet configuration)
Line 219: Line 219:
 
                 .NotFound.Ignore()
 
                 .NotFound.Ignore()
 
                 .Access.CamelCaseField(Prefix.Underscore);
 
                 .Access.CamelCaseField(Prefix.Underscore);
 +
</source>
 +
 +
== one to one ==
 +
<source lang="csharp">
 +
using System;
 +
using FluentNHibernate.Cfg;
 +
using FluentNHibernate.Cfg.Db;
 +
using NHibernate;
 +
using FluentNHibernate.Mapping;
 +
 +
namespace NhOneToOne
 +
{
 +
    public class Program
 +
    {
 +
        static void Main(string[] args)
 +
        {
 +
            try
 +
            {
 +
 +
                var sessionFactory = Fluently.Configure()
 +
                                            .Database(
 +
                                                    MsSqlConfiguration.MsSql2005
 +
                                                                      .ConnectionString(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=NHTest;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False")
 +
                                                                      .ShowSql()
 +
                                              )
 +
                                            .Mappings(m => m
 +
                                            .FluentMappings.AddFromAssemblyOf<Program>())
 +
                                            .BuildSessionFactory();
 +
 +
                ISession session = sessionFactory.OpenSession();
 +
 +
 +
                Child c = session.Get<Child>(1);
 +
                Parent p = c.Parent;
 +
                Child c2 = p.Child;
 +
 +
                session.Clear();
 +
 +
                p = session.Get<Parent>(2);
 +
                c2 = p.Child;             
 +
 +
            }
 +
            catch (Exception e)
 +
            {
 +
                Console.Write(e.Message);
 +
            }
 +
        }
 +
 +
    }
 +
 +
    public class Child
 +
    {
 +
        public virtual string Name { get; set; }
 +
        public virtual int Id { get; set; }
 +
 +
        public virtual Parent Parent { get; set; }
 +
    }
 +
 +
    public class Parent
 +
    {
 +
        public virtual string Name { get; set; }
 +
        public virtual int Id { get; set; }
 +
 +
        public virtual Child Child { get; set; }
 +
 +
    }
 +
 +
    public class ChildMap : ClassMap<Child>
 +
    {
 +
        public ChildMap()
 +
        {
 +
            Table("ChildTable");
 +
            Id(x => x.Id).GeneratedBy.Native();
 +
            Map(x => x.Name);
 +
 +
            References(x => x.Parent).Column("IdParent");
 +
 +
        }
 +
    }
 +
 +
    public class ParentMap : ClassMap<Parent>
 +
    {
 +
        public ParentMap()
 +
        {
 +
            Table("ParentTable");
 +
            Id(x => x.Id).GeneratedBy.Native();
 +
            Map(x => x.Name);
 +
 +
            HasOne(x => x.Child).PropertyRef("Parent");
 +
        }
 +
 +
    }
 +
}
 +
 
</source>
 
</source>
  

Revision as of 22:13, 8 March 2017

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);

one to one

using System;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using FluentNHibernate.Mapping;

namespace NhOneToOne
{
    public class Program
    {
        static void Main(string[] args)
        {
            try
            {

                var sessionFactory = Fluently.Configure()
                                             .Database(
                                                    MsSqlConfiguration.MsSql2005
                                                                      .ConnectionString(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=NHTest;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False")
                                                                      .ShowSql()
                                              )
                                             .Mappings(m => m
                                             .FluentMappings.AddFromAssemblyOf<Program>())
                                             .BuildSessionFactory();

                ISession session = sessionFactory.OpenSession();


                Child c = session.Get<Child>(1);
                Parent p = c.Parent;
                Child c2 = p.Child;

                session.Clear();

                p = session.Get<Parent>(2);
                c2 = p.Child;               
 
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }
        }

    }

    public class Child
    {
        public virtual string Name { get; set; }
        public virtual int Id { get; set; }

        public virtual Parent Parent { get; set; }
    }

    public class Parent
    {
        public virtual string Name { get; set; }
        public virtual int Id { get; set; }

        public virtual Child Child { get; set; }

    }

    public class ChildMap : ClassMap<Child>
    {
        public ChildMap()
        {
            Table("ChildTable");
            Id(x => x.Id).GeneratedBy.Native();
            Map(x => x.Name);

            References(x => x.Parent).Column("IdParent");

        }
    }

    public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            Table("ParentTable");
            Id(x => x.Id).GeneratedBy.Native();
            Map(x => x.Name);

            HasOne(x => x.Child).PropertyRef("Parent");
        }

    }
}

Queries

NHibernateQueries

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 die Entität bereits eine Id hat,  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();

Cascading bei Many to Many

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.
  • SaveUpdate(): Beide Entitäten werden in die Datenbank eingefügt.
  • Delete(): 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.
  • Merge(): 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.
  • All(): Beide Entitäten werden in die Datenbank eingefügt.
  • AllDeleteOrphan(): Beide Entitäten werden in die Datenbank eingefügt.

Delete

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

MyItem item = session.Get<MyItem>(27); //Item enthält ein Tag.

session.Delete(item);

tx.Commit(); 
              
session.Close();
  • None(): Nur MyItem wird gelöscht.
  • All(): MyItem und MyTag wird gelöscht.
  • Merge(): Nur MyItem wird gelöscht.
  • Delete(): MyItem und MyTag wird gelöscht.
  • DeleteAll(): MyItem und MyTag wird gelöscht.
  • DeleteOrphan(): MyItem und MyTag wird gelöscht.
  • AllDeleteOrphan(): MyItem und MyTag wird gelöscht.

Remove from collection

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

MyItem item = session.Get<MyItem>(37); //Item enthält ein Tag.

item.Tags.Clear();

tx.Commit(); 
              
session.Close();
  • None(): Tag wird nicht gelöscht. Verknüpfung zwischen Tag und Item wird entfernt.
  • All(): Tag wird nicht gelöscht. Verknüpfung zwischen Tag und Item wird entfernt.
  • Merge(): Tag wird nicht gelöscht. Verknüpfung zwischen Tag und Item wird entfernt.
  • Delete(): Tag wird nicht gelöscht. Verknüpfung zwischen Tag und Item wird entfernt.
  • DeleteAll(): Tag wird nicht gelöscht. Verknüpfung zwischen Tag und Item wird entfernt.
  • DeleteOrphan(): Tag wird gelöscht.
  • AllDeleteOrphan(): Tag wird gelöscht.

resourcen