Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Work With Fluent NHibernate in Core 2.0

DZone's Guide to

Work With Fluent NHibernate in Core 2.0

Read on to learn more about NHibernate, an object-relational mapping (ORM) framework. Also learn about what databases are supported by NHibernate.

· Database Zone ·
Free Resource

Discover Tarantool's unique features which include powerful stored procedures, SQL support, smart cache, and the speed of 1 million ACID transactions on a single CPU core!

Table of Contents

  • Introduction
  • NuGet package
    • Create Entities
      • Person Entity
      • Task Entity
  • Create Mappings
    • PersonMap
    • TaskMap
    • PersonService
  • Conclusion

Introduction

NHibernate is an object-relational mapping (ORM) framework that allows you to map the object-oriented domain model with the tables in a relational Database. To realize the mapping, we have to write XML mapping files (.hbm.xml files), and to make it easier, here comes Fluent NHibernate as an abstraction layer to do it in C# rather than XML.

Databases supported by NHibernate are:

  • SQL Server
  • SQL Server Azure
  • Oracle
  • PostgreSQL
  • MySQL
  • SQLite
  • DB2;
  • Sybase Adaptive Server
  • Firebird
  • Informix

It can even support the use of OLE DB (Object Linking and Embedding) and ODBC (Open Database Connectivity).

What makes NHibernate stronger than Entity Framework is that it integrates querying API sets like LINQ, Criteria API (implementation of the pattern Query Object), integration with Lucene.NET, use of SQL, and even stored procedures.

NHibernate also supports:

  • Second Level Cache (used among multiple ISessionFactory)
  • Multiple ways of ID generation such as Identity, Sequence, HiLo, GUID, Pooled, and the Native mechanism used in databases
  • Flushing properties (FlushMode properties in ISession that can take these values: Auto, Commit, or Never)
  • Lazy Loading
  • Generation and updating system like migration API in Entity framework (Like Code First)

When Microsoft started working on the framework Core, much of the functionality in NHibernate wasn’t supported in .NET Core as target platform, but from the version Core 2.0, we can integrate NHibernate and Fluent NHibernate.

  1. NuGet package

The NuGet package to use Fluent NHibernate:

PM> Install-Package FluentNHibernate -Version 2.1.2

  1. Create Entities

This folder will include two entities: Person and Task.

    1. Person Entity
public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual DateTime CreationDate { get; set; }
public virtual DateTime UpdatedDate { get; set; }
}


    1. Task Entity
    public class Task
    {
    public virtual string Id { get; set; }
    public virtual string Title { get; set; }
    
    public virtual string Description { get; set; }
    
    public virtual DateTime CreationTime { get; set; }
    
    public virtual TaskState State { get; set; }
    
    public virtual Person AssignedTo { get; set; }
    
    public virtual DateTime CreationDate { get; set; }
    public virtual DateTime UpdatedDate { get; set; }
    
    public Task()
    {
    CreationTime = DateTime.UtcNow;
    State = TaskState.Open;
    }
    
    }
    
    public enum TaskState : byte
    {
    /// <summary>
    /// The task is Open.
    /// </summary>
    Open = 0,
    /// <summary>
    /// The task is active.
    /// </summary>
    Active = 1,
    
    /// <summary>
    /// The task is completed.
    /// </summary>
    Completed = 2,
    
    /// <summary>
    /// The task is closed.
    /// </summary>
    Closed = 3
    }
  1. Create Mappings

This folder will contain the mapping classes for the previous entities.

    1. PersonMap
    public class PersonMap : ClassMap<Person>
    {
    public PersonMap()
    {
    Id(x => x.Id);
    
    Map(x => x.Name);
    
    Map(x => x.CreationDate);
    Map(x => x.UpdatedDate);
    }
    }
  1. TaskMap
public class TaskMap : ClassMap<Task>
{
public TaskMap()
{
Id(x => x.Id);

Map(x => x.CreationTime);
Map(x => x.State);
Map(x => x.Title);
Map(x => x.Description);
Map(x => x.UpdatedDate);
Map(x => x.CreationDate);

References(x => x.AssignedTo);
}
}
  1. Create the SessionFactory Builder

The folder SessionFactories, we will include the class of SessionFactoryBuilder that will manage the schema builder and SessionFactory builder.

public class SessionFactoryBuilder
 {

 //var listOfEntityMap = typeof(M).Assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(M))).ToList();
 //var sessionFactory = SessionFactoryBuilder.BuildSessionFactory(dbmsTypeAsString, connectionStringName, listOfEntityMap, withLog, create, update);



 public static ISessionFactory BuildSessionFactory(string connectionStringName, bool create = false, bool update = false)
 {
 return Fluently.Configure()
 .Database(PostgreSQLConfiguration.Standard
 .ConnectionString(ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString))
 //.Mappings(m => entityMappingTypes.ForEach(e => { m.FluentMappings.Add(e); }))
 .Mappings(m =>m.FluentMappings.AddFromAssemblyOf<NHibernate.Cfg.Mappings>())
 .CurrentSessionContext("call")
 .ExposeConfiguration(cfg => BuildSchema(cfg, create, update))
 .BuildSessionFactory();
 }


 /// <summary>
 /// Build the schema of the database.
 /// </summary>
 /// <param name="config">Configuration.</param>
 private static void BuildSchema(Configuration config, bool create = false, bool update = false)
 {
 if (create)
 {
 new SchemaExport(config).Create(false, true);
 }
 else
 {
 new SchemaUpdate(config).Execute(false, update);
 }
 }
}
  1. Create Services

This folder will include all different treatments that we can do, like the GetAll element of an entity, and add a new element in the database. For example, in this sample, I will include two services according to our entities.

    1. PersonService
public class PersonService
{
public static void GetPerson(Person person)
{
Console.WriteLine(person.Name);
Console.WriteLine();
}
}
    1. TaskService
    public class TaskService
    {
    public static void GetTaskInfo(Task task)
    
    {
    
    Console.WriteLine(task.Title);
    Console.WriteLine(task.Description);
    Console.WriteLine(task.State);
    Console.WriteLine(task.AssignedTo.Name);
    Console.WriteLine();
    
    }
    }
  1. Add and display Table content

Now, we will try to display data from the database or add a new element.

In the program, we will start by creating a session factory using the method: BuildSessionFactory implemented inside the class SessionFactoryBuilder. After, we will open a new session for every transaction done. We start a new transaction inside, and it depends on the operation whether or not we need to insert a new line in the database. We use session.SaveOrUpdate(MyObjectToAdd); after we commit this using this transaction: transaction.Commit();

static void Main(string[] args)

    {
        // create our NHibernate session factory

        string connectionStringName = "add here your connection string";

        var sessionFactory = SessionFactoryBuilder.BuildSessionFactory(connectionStringName, true, true);

        using (var session = sessionFactory.OpenSession())
        {
            // populate the database

            using (var transaction = session.BeginTransaction()

            {
                // create a couple of Persons

                var person1 = new Person { Name = "Rayen Trabelsi" };

                var person2 = new Person { Name = "Mohamed Trabelsi" };

                var person3 = new Person { Name = "Hamida Rebai" };

                //create tasks

                var task1 = new Task {Title = "Task 1", State = TaskState.Open, AssignedTo = person1};

                var task2 = new Task { Title = "Task 2", State = TaskState.Closed, AssignedTo = person2 };

                var task3 = new Task { Title = "Task 3", State = TaskState.Closed, AssignedTo = person3 };

                // save both stores, this saves everything else via cascading

                session.SaveOrUpdate(task1);

                session.SaveOrUpdate(task2);

                session.SaveOrUpdate(task3);

                transaction.Commit();
            }

           using (var session2 = sessionFactory.OpenSession())

            {

               //retreive all tasks with person assigned to

                using (session2.BeginTransaction())

                {

                   var tasks = session.CreateCriteria(typeof(Task))

                        .List<Task>();

                   foreach (var task in tasks)

                    {
                        TaskService.GetTaskInfo(task);
                   }

                }

            }

           Console.ReadKey();

        }

   }

}

Conclusion

This is a sample of Fluent NHibernate. In another article, I will show you another web sample using some of the advantages like Criteria APIs.

Discover Tarantool's unique features such as powerful stored procedures, SQL support, smart cache, and the speed of 1 million ACID transactions on a single CPU.

Topics:
nhibernate ,asp ,orm

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}