Building a MVC2 Template, Part 18, Adding NHibernate

3 Comments

Here is the long awaited post that deals directly with adding NHibernate to our MVC2 template project. This post will present the code that gives our providers (Membership, Role, and Profile) access to the database. This implementation of the IProviderRepository interface will use NHibernate.

SolutionExplorer17_01

The first thing we want to do is add all the necessary NHibernate references to our Nehemiah.Data project. The screen shot above shows all the references. All but the NHibernate.Linq dll will be found in the Fluent NHibernate folder within our CodeVault. You will also need to add a reference to the Service.Logging project. Next create a folder named NHibernate with two subfolders named Mappings and SessionFactories.

Interfaces

If you have been following this series of posts you will already have a file named IProviderRepository.cs in the Nehemiah.Data project. Update that file with the code below. There are a few minor changes that add a couple of methods that will be used in later parts of the project.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Nehemiah.Data.Models;

namespace Nehemiah.Data
{
    public interface IProviderRepository
    {

        #region - Profile -
        bool Add(string applicationName, Profile profile);
        IList<Profile> GetAllProfiles(string applicationName, bool authenticated, DateTime inactiveDate);
        bool Save(string applicationName, Profile profile);
        Profile GetProfileByUserName(string applicationName, string userName);
        bool DeleteProfile(string applicationName, string userName);
        bool DeleteProfile(string applicationName, Guid userId);
        IList<Profile> GetProfileList(string applicationName, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, bool authenticated, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, DateTime inactiveDate, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, bool authenticated, DateTime inactiveDate, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, string username, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, bool authenticated, string username, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, DateTime inactiveDate, string username, int index, int pageSize);
        IList<Profile> GetProfileList(string applicationName, bool authenticated, DateTime inactiveDate, string username, int index, int pageSize);
        int NumberOfProfiles(string applicationName);
        int NumberOfProfiles(string applicationName, bool authenticated);
        int NumberOfProfiles(string applicationName, DateTime inactiveDate);
        int NumberOfProfiles(string applicationName, DateTime inactiveDate, string userName);
        int NumberOfProfiles(string applicationName, bool authenticated, DateTime inactiveDate);
        int NumberOfProfiles(string applicationName, string username);
        int NumberOfProfiles(string applicationName, bool authenticated, string username);
        int NumberOfProfiles(string applicationName, bool authenticated, DateTime inactiveDate, string userName);
        #endregion

        #region - Role -
        bool Add(string applicationName, Role role);
        bool DeleteRole(string applicationName, string roleName);
        bool DeleteRole(Role role);
        IList<Role> GetAllRoles(string applicationName);
        Role GetRoleByRoleName(string applicationName, string roleName);
        Role GetRoleByKey(string applicationName, int roleId);
        IList<Role> GetRoleList(string applicationName, int index, int pageSize);
        IList<Role> GetRoleListByRoleName(string applicationName, string roleName, int index, int pageSize);
        int NumberOfRoles(string applicationName);
        bool Save(string applicationName, Role role);
        IList<Role> GetRolesForUser(string applicationName, Guid userId);
        IList<Role> GetRolesForUser(string applicationName, string username);
        #endregion

        #region - User -
        bool Add(string applicationName, User user);
        bool DeleteUser(string applicationName, string username);
        bool DeleteUser(User user);
        IList<User> GetAllUsers(string applicationName);
        User GetUserByUserName(string applicationName, string username);
        User GetUserByKey(string applicationName, Guid userId);
        User GetUserByEmail(string applicationName, string email);
        IList<User> GetUserList(string applicationName, int index, int pageSize);
        IList<User> GetUserListByEmail(string applicationName, string email, int index, int pageSize);
        IList<User> GetUserListByUserName(string applicationName, string username, int index, int pageSize);
        int NumberOfUsers(string applicationName);
        int NumberOfUsersByEmail(string applicationName, string email);
        int NumberOfUsersByUserName(string applicationName, string userName);
        int NumberOfUsersOnline(string applicationName, int timeWindow);
        bool Save(string applicationName, User user);
        IList<User> GetUsersInRole(string applicationName, string rolename);
        IList<User> GetUsersInRole(string applicationName, string rolename, string username);
        #endregion

        #region - UserInRole -
        bool AddUserToRole(string applicationName, string userName, string roleName);
        int NumberOfUsersInRole(string applicationName, int roleId);
        int NumberOfUsersInRole(string applicationName, string roleName);
        bool DeleteUserInRole(string userName, string roleName);
        bool DeleteUserInRole(UserInRole userInRole);
        IList<UserInRole> GetAllUserInRole(string applicationName);
        #endregion

    }   // End Interface

}       // End Namespace

In the SessionFactories folder add an interface named IFluentSessionFactory. The code for this interface is listed below.

using NHibernate;
using FluentNHibernate.Cfg;

namespace Nehemiah.Data.NHibernate
{
    public interface IFluentSessionFactory
    {
        ISessionFactory CreateSessionFactory();
    }
}

NHibernate uses a Session object to interface to the database. It uses a SessionFactory to create the Session object for your application. We can use a different database by using a different SessionFactory. In our template we will use Ninject to inject the SessionFactory of our choosing. This will allow us, if we choose, to use SQLite for our automated specifications testing and SQL Server for the application.

Class Objects

Just to make sure the User, Role, and UserInRole classes are up to date, here is the code for all three classes. These will be found in the Models folder of the Nehemiah.Data project. These are very simple classes.

You should also notice that all of the properties are marked virtual. This is a requirement for NHibernate. If they aren’t virtual then NHibernate will not be able to find them.

The code for User.cs is shown below.

using System;
using System.Collections.Generic;

namespace Nehemiah.Data.Models
{

    public partial class User
    {

        public virtual Guid UserId { get; set; }
        public virtual string ApplicationName { get; set; }
        public virtual string UserName { get; set; }
        public virtual string Email { get; set; }
        public virtual string Comment { get; set; }
        public virtual string Password { get; set; }
        public virtual string PasswordQuestion { get; set; }
        public virtual string PasswordAnswer { get; set; }
        public virtual DateTime? LastActivityDate { get; set; }
        public virtual DateTime? LastLoginDate { get; set; }
        public virtual DateTime? LastPasswordChangedDate { get; set; }
        public virtual DateTime CreationDate { get; set; }
        public virtual bool Approved { get; set; }
        public virtual bool Online { get; set; }
        public virtual bool LockedOut { get; set; }
        public virtual DateTime? LastLockedOutDate { get; set; }
        public virtual int FailedPasswordAttemptCount { get; set; }
        public virtual DateTime? FailedPasswordAttemptWindowStart { get; set; }
        public virtual int FailedPasswordAnswerAttemptCount { get; set; }
        public virtual DateTime? FailedPasswordAnswerAttemptStartWindow { get; set; }

        public virtual IList<Role> Roles { get; set; }

        public User()
        {
            Approved = false;
            CreationDate = DateTime.UtcNow;
            FailedPasswordAnswerAttemptCount = 0;
            FailedPasswordAnswerAttemptStartWindow = null;
            FailedPasswordAttemptCount = 0;
            FailedPasswordAttemptWindowStart = null;
            LastActivityDate = DateTime.UtcNow;
            LastLockedOutDate = null;
            LastLoginDate = null;
            LastPasswordChangedDate = null;
            LockedOut = false;
            Online = false;

            Roles = new List<Role>();

        }

        public User(string applicationName, string username, string email, string password, string passwordQuestion, string passwordAnswer, bool isApproved, string comment)
            : this()
        {
            ApplicationName = applicationName;
            UserName = username;
            Email = email;
            Password = password;
            PasswordQuestion = passwordQuestion;
            PasswordAnswer = passwordAnswer;
            Approved = isApproved;
            Comment = comment;
        }

        public virtual void AddRole(Role role)
        {
            if (role.ApplicationName == ApplicationName)
            {
                //role.Users.Add(this);
                Roles.Add(role);
            }
        }

        public virtual void DeleteRole(Role role)
        {
            //Roles.Remove(role);
            foreach (var r in Roles)
            {
                if (r.ApplicationName == role.ApplicationName && r.RoleName == role.RoleName)
                {
                    Roles.Remove(r);
                    break;
                }
            }
        }

        public virtual bool HasRole(string rolename)
        {
            bool success = false;
            foreach (Role role in Roles)
            {
                if (role.RoleName == rolename)
                {
                    success = true;
                    break;
                }
            }
            return success;
        }

    }   // End Class

}       // End Namespace

This is the code for Role.cs.

using System;
using System.Collections.Generic;
using System.Text;

namespace Nehemiah.Data.Models
{

    public partial class Role
    {
        public virtual int RoleId { get; set; }
        public virtual string ApplicationName { get; set; }
        public virtual string RoleName { get; set; }

        public Role() { }

        public Role(string application, string name)
            : this()
        {
            ApplicationName = application;
            RoleName = name;
        }

    }   // End Class

}       // End Namespace

Lastly, here is the code for UserInRole.cs.

using System;
using System.Collections.Generic;
using System.Text;

namespace Nehemiah.Data.Models
{
    public partial class UserInRole
    {

        public virtual Guid UserId { get; set; }
        public virtual int RoleId { get; set; }

        public UserInRole() { }

        public UserInRole(Guid userId, int roleId)
            : this()
        {
            UserId = userId;
            RoleId = roleId;
        }

    }   // End Class

}       // End Namespace

Mapping Tables to Class Objects

In the Mappings folder create a class file named UserClassMap.cs. This is where we will use Fluent NHibernate to describe the mapping. Originally I was going to use (and tried using, but without the success I was looking for) an In-Memory database. That’s why the mapping classes are very explicit.

The mapping class for the User object is shown below and is identical to the mapping class presented in the previous post, with one exception. It seems odd to me, but for a many-to-many relationship Cascade needs to be set to None. After you get all the code entered and the specifications pass testing, try changing the Cascade setting to see the effects on the test results.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Mapping;
using Nehemiah.Data.Models;

namespace Nehemiah.Data.NHibernate.Mappings
{
    public class UserClassMap : ClassMap<User>
    {
        public UserClassMap()
        {
            Table("[User]");
            Id(x => x.UserId).Column("UserId").Unique().GeneratedBy.Guid();
            Map(x => x.ApplicationName).Column("ApplicationName").UniqueKey("AppUser").Not.Nullable().Length(50);
            Map(x => x.UserName).Column("UserName").UniqueKey("AppUser").Not.Nullable().Length(50);
            Map(x => x.Email).Column("Email").Not.Nullable().Length(255);
            Map(x => x.Comment).Column("Comment").Nullable().Length(255);
            Map(x => x.Password).Column("Password").Not.Nullable().Length(50);
            Map(x => x.PasswordQuestion).Column("PasswordQuestion").Nullable().Length(255);
            Map(x => x.PasswordAnswer).Column("PasswordAnswer").Nullable().Length(50);
            Map(x => x.LastActivityDate).Column("LastActivityDate").Nullable();
            Map(x => x.LastLoginDate).Column("LastLoginDate").Nullable();
            Map(x => x.LastPasswordChangedDate).Column("LastPasswordChangedDate").Nullable();
            Map(x => x.CreationDate).Column("CreationDate").Not.Nullable();
            Map(x => x.Approved).Column("Approved").Not.Nullable();
            Map(x => x.Online).Column("Online").Not.Nullable();
            Map(x => x.LockedOut).Column("LockedOut").Not.Nullable();
            Map(x => x.LastLockedOutDate).Column("LastLockedOutDate").Nullable();
            Map(x => x.FailedPasswordAttemptCount).Column("FailedPasswordAttemptCount").Not.Nullable();
            Map(x => x.FailedPasswordAttemptWindowStart).Column("FailedPasswordAttemptWindowStart").Nullable();
            Map(x => x.FailedPasswordAnswerAttemptCount).Column("FailedPasswordAnswerAttemptCount").Not.Nullable();
            Map(x => x.FailedPasswordAnswerAttemptStartWindow).Column("FailedPasswordAnswerAttemptStartWindow").Nullable();

            HasManyToMany<Role>(x => x.Roles)
                .Not.LazyLoad()
                .Table("UserInRole")
                .ParentKeyColumn("UserId")
                .ChildKeyColumn("RoleId")
                .NotFound.Ignore()
                .Cascade.None()
                ;
        }
    }
}

Now lets create a mapping class for our Role object.

using FluentNHibernate.Mapping;
using Nehemiah.Data.Models;

namespace Nehemiah.Data.NHibernate.Mappings
{
    public class RoleClassMap : ClassMap<Role>
    {
        public RoleClassMap()
        {
            Table("Role");
            Id(x => x.RoleId).Column("RoleId").Unique().GeneratedBy.Identity();
            Map(x => x.ApplicationName).Column("ApplicationName").UniqueKey("AppRole").Not.Nullable().Length(50);
            Map(x => x.RoleName).Column("RoleName").UniqueKey("AppRole").Not.Nullable().Length(50);
        }
    }
}

We do not need to create a mapping class for the UserInRole table. The Profile mapping class will be addresses in a future post.

Session Factories

The first session factory presented is for SQLite.

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;

namespace Nehemiah.Data.NHibernate
{

    public class SQLiteSessionFactory : IFluentSessionFactory
    {
        private static ISessionFactory SessionFactory = null;
        private static FluentConfiguration SessionConfiguration = null;

        public ISessionFactory CreateSessionFactory()
        {

            if (SessionFactory == null)
            {
                SessionConfiguration = Fluently.Configure();

                //SessionConfiguration.Database(SQLiteConfiguration.Standard.InMemory)
                SessionConfiguration.Database(SQLiteConfiguration.Standard.UsingFile("Nehemiah.db3")
                    .ShowSql())
                    .ExposeConfiguration(BuildSchema)
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<NHibernateRepository>()
                    .ExportTo(@"C:\development\Erictopia\Nehemiah\Nehemiah\bin")
                    );

                SessionFactory = SessionConfiguration.BuildSessionFactory();
            }

            return SessionFactory;
        }

        private static void BuildSchema(Configuration cfg)
        {
            new SchemaExport(cfg).Create(true, true);
            //export.Execute(false, true, false);
        }

    }   // End Class

}       // End Namespace

The SessionFactory used in the template is SQL2005SessionFactory.cs. Though you can substitute your own if you prefer. The code is below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using Nehemiah.Data.NHibernate.Mappings;

namespace Nehemiah.Data.NHibernate
{
    public class SQL2005SessionFactory : IFluentSessionFactory
    {
        private static ISessionFactory SessionFactory = null;
        private static FluentConfiguration Configuration = null;

        public ISessionFactory CreateSessionFactory()
        {

            if (SessionFactory == null)
            {
                Configuration = Fluently.Configure();

                Configuration.Database(MsSqlConfiguration.MsSql2005.ShowSql().ConnectionString(c => c.FromConnectionStringWithKey("Nehemiah")))
                    .ExposeConfiguration(c => c.SetProperty("current_session_context_class", "web"))
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<NHibernateRepository>()
                    );

                SessionFactory = Configuration.BuildSessionFactory();
            }

            return SessionFactory;
        }

    }   // End Class

}       // End Namespace

While creating this portion of the project I ran into issues with the specifications not passing the tests. I switched to the SQL Server SessionFactory so I could use the tools I already had installed to examine the database and make the necessary updates to the code and to the tests.

NHibernate Repository

In the NHibernate folder create a class file named Session.cs and put the code below in the file.

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using Nehemiah.Data.NHibernate.Mappings;
using NHibernate;

namespace Nehemiah.Data.NHibernate
{
    public class NHibernateSession
    {

        private static IFluentSessionFactory SessionFactory = null;
        private static ISession _session = null;

        public NHibernateSession(IFluentSessionFactory sessionFactory)
        {
            SessionFactory = sessionFactory;
        }

        public static ISession OpenSession()
        {
            if (_session == null)
            {
                _session = SessionFactory.CreateSessionFactory().OpenSession();
            }

            if (_session.IsOpen == false)
            {
                _session = _session.SessionFactory.OpenSession();
            }

            return _session;
        }

        public static ISession OpenSession(IFluentSessionFactory sessionFactory)
        {
            if (SessionFactory == null)
            {
                SessionFactory = sessionFactory;
            }
            return OpenSession();
        }

    }   // End Class

}       // End Namespace

Next create a class named NHibernateRepository.cs using the code below.

using System;
using System.Collections.Generic;
using System.Linq;
using Nehemiah.Data.Models;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;
using NHibernate.Transform;
using Service.Logging;

namespace Nehemiah.Data.NHibernate
{

    public class NHibernateRepository : IProviderRepository
    {

        private static ILogger Logger;
        private static IFluentSessionFactory SessionFactory;

        public NHibernateRepository()
        {
        }

        public NHibernateRepository(IFluentSessionFactory sessionFactory, ILogger logger)
            : this()
        {
            SessionFactory = sessionFactory;
            Logger = logger;
        }

        private ISession Session
        {
            get { return NHibernateSession.OpenSession(SessionFactory); }
        }

        #region - Profile -

        public bool Add(string applicationName, Profile profile)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetAllProfiles(string applicationName, bool authenticated, DateTime inactiveDate)
        {
            throw new NotImplementedException();
        }

        public bool Save(string applicationName, Profile profile)
        {
            throw new NotImplementedException();
        }

        public Profile GetProfileByUserName(string applicationName, string userName)
        {
            throw new NotImplementedException();
        }

        public bool DeleteProfile(string applicationName, string userName)
        {
            throw new NotImplementedException();
        }

        public bool DeleteProfile(string applicationName, Guid userId)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, bool authenticated, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, DateTime inactiveDate, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, bool authenticated, DateTime inactiveDate, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, string username, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, bool authenticated, string username, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, DateTime inactiveDate, string username, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public IList<Profile> GetProfileList(string applicationName, bool authenticated, DateTime inactiveDate, string username, int index, int pageSize)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, bool authenticated)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, DateTime inactiveDate)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, DateTime inactiveDate, string userName)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, bool authenticated, DateTime inactiveDate)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, string username)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, bool authenticated, string username)
        {
            throw new NotImplementedException();
        }

        public int NumberOfProfiles(string applicationName, bool authenticated, DateTime inactiveDate, string userName)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region - Role -

        /// <summary>
        ///
        /// </summary>
        private IQueryable<Role> Roles
        {
            get { return Session.Linq<Role>(); }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="rolename"></param>
        public int NumberOfUsersInRole(string applicationName, string rolename)
        {
            return Session
                    .CreateSQLQuery(@"SELECT Count(*) AS cnt
                                        FROM [User] U
                                        INNER JOIN UserInRole X ON X.UserId = U.UserId
                                        INNER JOIN Role R ON R.RoleId = X.RoleId
                                        WHERE U.ApplicationName = ? AND R.RoleName = ?"
                                        )
                    .AddScalar("cnt", NHibernateUtil.Int32)
                    .SetString(0, applicationName)
                    .SetString(1, rolename)
                    .UniqueResult<int>();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        public bool Add(string applicationName, Role role)
        {
            bool Success = false;
            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Save(role);
                        transaction.Commit();
                        Success = true;
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        /// <summary>
        /// Removes the defined role from the data repository.
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public bool DeleteRole(string applicationName, string roleName)
        {
            Role role;
            bool Success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        role = GetRoleByRoleName(applicationName, roleName);
                        if (role != null)
                        {
                            session.Delete(role);
                            transaction.Commit();
                            Success = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        public bool DeleteRole(Role role)
        {
            bool success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        if (role != null)
                        {
                            session.Delete(role);
                            transaction.Commit();
                            success = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                        throw;
                    }
                }
            }
            return success;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <returns></returns>
        public IList<Role> GetAllRoles(string applicationName)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName
                    orderby r.RoleName
                    select r).ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public Role GetRoleByRoleName(string applicationName, string roleName)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName && r.RoleName == roleName
                    select r).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public Role GetRoleByKey(string applicationName, int roleId)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName && r.RoleId == roleId
                    select r).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="index"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<Role> GetRoleList(string applicationName, int index, int pageSize)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName
                    orderby r.RoleName
                    select r)
                    .Skip(index * pageSize)
                    .Take(pageSize)
                    .ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="roleName"></param>
        /// <param name="index"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<Role> GetRoleListByRoleName(string applicationName, string roleName, int index, int pageSize)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName && r.RoleName.Contains(roleName)
                    orderby r.RoleName
                    select r)
                    .Skip(index * pageSize)
                    .Take(pageSize)
                    .ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <returns></returns>
        public int NumberOfRoles(string applicationName)
        {
            return (from r in Roles
                    where r.ApplicationName == applicationName
                    select r).Count();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        public bool Save(string applicationName, Role role)
        {
            bool success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.SaveOrUpdate(role);
                        transaction.Commit();
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return success;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IList<Role> GetRolesForUser(string applicationName, Guid userId)
        {
            User user = GetUserByKey(applicationName, userId);

            if (user == null)
                return new List<Role>();

            if (user.Roles == null)
                user.Roles = new List<Role>();

            return user.Roles.ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public IList<Role> GetRolesForUser(string applicationName, string username)
        {

            User user = GetUserByUserName(applicationName, username);

            if (user == null)
                return new List<Role>();

            if (user.Roles == null)
                user.Roles = new List<Role>();

            return user.Roles.ToList();
        }

        #endregion

        #region - User -

        /// <summary>
        ///
        /// </summary>
        private IQueryable<User> Users
        {
            get { return Session.Linq<User>(); }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <returns></returns>
        public IList<User> GetAllUsers(string applicationName)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName
                    orderby u.UserName
                    select u).ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool Add(string applicationName, User user)
        {
            bool Success = false;
            Logger.Info(string.Format("Adding User: {0}", (user != null) ? user.UserName : "user is NULL"));
            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Save(user);
                        transaction.Commit();
                        Success = true;
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool DeleteUser(string applicationName, string username)
        {
            User user;
            bool Success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        user = GetUserByUserName(applicationName, username);
                        if (user != null)
                        {
                            session.Delete(user);
                            transaction.Commit();
                            Success = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        public bool DeleteUser(User user)
        {
            bool Success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        if (user != null)
                        {
                            session.Delete(user);
                            transaction.Commit();
                            Success = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public User GetUserByUserName(string applicationName, string username)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.UserName == username
                    select u).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public User GetUserByKey(string applicationName, Guid userId)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.UserId == userId
                    select u).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="email"></param>
        /// <returns></returns>
        public User GetUserByEmail(string applicationName, string email)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.Email == email
                    select u).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="index"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<User> GetUserList(string applicationName, int index, int pageSize)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName
                    orderby u.UserName
                    select u)
                    .Skip(index * pageSize)
                    .Take(pageSize)
                    .ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="email"></param>
        /// <param name="index"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<User> GetUserListByEmail(string applicationName, string email, int index, int pageSize)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.Email.Contains(email)
                    orderby u.UserName
                    select u)
                    .Skip(index * pageSize)
                    .Take(pageSize)
                    .ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="username"></param>
        /// <param name="index"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<User> GetUserListByUserName(string applicationName, string username, int index, int pageSize)
        {
            return (from u in Session.Linq<User>() /*Users*/
                    where u.ApplicationName == applicationName && u.UserName.Contains(username)
                    orderby u.UserName
                    select u)
                    .Skip(index * pageSize)
                    .Take(pageSize)
                    .ToList();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <returns></returns>
        public int NumberOfUsers(string applicationName)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName
                    select u).Count();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="email"></param>
        /// <returns></returns>
        public int NumberOfUsersByEmail(string applicationName, string email)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.Email.Contains(email)
                    select u).Count();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public int NumberOfUsersByUserName(string applicationName, string userName)
        {
            return (from u in Users
                    where u.ApplicationName == applicationName && u.UserName.Contains(userName)
                    select u).Count();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="timeWindow"></param>
        /// <returns></returns>
        public int NumberOfUsersOnline(string applicationName, int timeWindow)
        {
            DateTime threshold = DateTime.UtcNow.AddMinutes(-1.0 * timeWindow);

            return (from u in Users
                    where u.ApplicationName == applicationName && u.LastActivityDate != null && u.LastActivityDate >= threshold
                    select u).Count();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool Save(string applicationName, User user)
        {
            bool success = false;

            Logger.Info(string.Format("Saving user {0}", user.UserName));
            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.SaveOrUpdate(user);
                        transaction.Commit();
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return success;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="rolename"></param>
        /// <returns></returns>
        public IList<User> GetUsersInRole(string applicationName, string rolename)
        {
            // Using a SQL query because Join is not supported
            return Session
                    .CreateSQLQuery(@"SELECT U.* FROM [User] U
                                        INNER JOIN UserInRole X ON X.UserId = U.UserId
                                        INNER JOIN Role R ON R.RoleId = X.RoleId
                                        WHERE U.ApplicationName = ? AND R.RoleName = ?")
                    .AddEntity(typeof(User))
                    .SetString(0, applicationName)
                    .SetString(1, rolename)
                    .List<User>();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="rolename"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public IList<User> GetUsersInRole(string applicationName, string rolename, string username)
        {
            return Session
                    .CreateSQLQuery(@"SELECT U.* FROM [User] U
                                        INNER JOIN UserInRole X ON X.UserId = U.UserId
                                        INNER JOIN Role R ON R.RoleId = X.RoleId
                                        WHERE U.ApplicationName = ? AND R.RoleName = ? AND U.UserName LIKE ?")
                    .AddEntity(typeof(User))
                    .SetString(0, applicationName)
                    .SetString(1, rolename)
                    .SetString(2, "%" + username + "%")
                    .List<User>();
        }

        #endregion

        #region - UserInRole -

        /// <summary>
        ///
        /// </summary>
        private IQueryable<UserInRole> UserInRoles
        {
            get { return Session.Linq<UserInRole>(); }
        }

        public bool AddUserToRole(string applicationName, string userName, string roleName)
        {
            throw new NotImplementedException();
        }

        public int NumberOfUsersInRole(string applicationName, int roleId)
        {
            throw new NotImplementedException();
        }

        public bool DeleteUserInRole(string userName, string roleName)
        {
            throw new NotImplementedException();
        }

        public bool DeleteUserInRole(UserInRole userInRole)
        {
            bool Success = false;

            using (ISession session = Session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        if (userInRole != null)
                        {
                            session.Delete(userInRole);
                            transaction.Commit();
                            Success = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Logger.Error(ex);
                        throw;
                    }
                }
            }

            return Success;
        }

        public IList<UserInRole> GetAllUserInRole(string applicationName)
        {
            return (from x in UserInRoles
                    join u in Users on x.UserId equals u.UserId
                    where u.ApplicationName == applicationName
                    select x).ToList();
        }

        #endregion

    }   // End Class

}       // End Namespace

That’s all for this installment. Part 19 will address main project. Those updates will inject our ProviderRepository of choice (NHibernate) and the desired SessionFactory (SQLServer). We will also create the tables that will contain our data, have a successful build, and see all the specifications pass testing.’

References

Previous Articles in this Series

Shout it


Kick It on DotNetKicks.com
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

3 Comments (+add yours?)

  1. badmash
    Oct 22, 2010 @ 23:08:10

    I just signed up to your blogs rss feed. Will you post more on this subject?

  2. Eric
    Oct 24, 2010 @ 23:28:31

    Yes I will. The next post will be available on Oct 25 followed by another on Oct 28.

Leave a Reply

Comment moderation is enabled. Your comment may take some time to appear.