Linq to NHibernate入门示例

Linq to NHibernate入门示例

NHibernate相关:

       在微软发布C# 3.0后, LINQ在项目中发挥了重要作用。作为3.0语言身份的象征之一,学习LINQ有为重要。而NHibernate作为运用最广的ORM框架之一,在大型项目中广受开发人员的青睐。前不久,NHibernate Forge宣布NHiberante Linq 1.0正式发布了(参考)。 Linq to NHibernate有机的在NHibernate结合了Linq的查询功能,良好的把LINQ表达式转换为Criteria API。下面针对Linq to NHibernate做一个简单的Demo。

 

      一、建立一个类名为NHibernateHelper的类

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using NHibernate;

using NHibernate.Cfg;

using System.Web;



namespace DBUtility

{

    public sealed class NHibernateHelper

    {

        private const string CurrentSessionKey = "nhibernate.current_session";

        private static readonly ISessionFactory sessionFactory;



        static NHibernateHelper()

        {

            sessionFactory = new Configuration().Configure().BuildSessionFactory();

        }



        public static ISession GetCurrentSession()

        {

            HttpContext context = HttpContext.Current;

            ISession currentSession = context.Items[CurrentSessionKey] as ISession;



            if (currentSession == null)

            {

                currentSession = sessionFactory.OpenSession();

                context.Items[CurrentSessionKey] = currentSession;

            }



            return currentSession;

        }



        public static void CloseSession()

        {

            HttpContext context = HttpContext.Current;

            ISession currentSession = context.Items[CurrentSessionKey] as ISession;



            if (currentSession == null)

            {

                // No current session

                return;

            }



            currentSession.Close();

            context.Items.Remove(CurrentSessionKey);

        }



        public static void CloseSessionFactory()

        {

            if (sessionFactory != null)

            {

                sessionFactory.Close();

            }

        }

    }



}

      二、使用sql2k自带的northwind数据中的Products表为,建立Products实体和对应的Products.hbm.xml文件加上Categories和Categories.hbm.xml。

 

/*

Class Library : Domain

Author        : Liudong

Create Date   : 2009-10-15

*/

using System;

using System.Collections;

using System.Collections.Generic;

using System.Runtime.Serialization;



namespace Domain.Entities

{

    Products#region Products

    

    /// <summary>

    /// Entitiy:Products object for NHibernate mapped table 

    /// </summary>

    [DataContract]

    public partial class Products

    {

        ProductID#region ProductID  

    

        /// <summary>

        /// Field:ProductID 

        /// </summary>

        [DataMember]

        public virtual int? ProductID { get; set; }

        

        #endregion   

        

        ProductName#region ProductName  

    

        /// <summary>

        /// Field:ProductName 

        /// </summary>

        [DataMember]

        public virtual string ProductName { get; set; }

        

        #endregion   

        

        QuantityPerUnit#region QuantityPerUnit  

    

        /// <summary>

        /// Field:QuantityPerUnit 

        /// </summary>

        [DataMember]

        public virtual string QuantityPerUnit { get; set; }

        

        #endregion   

        

        UnitPrice#region UnitPrice  

    

        /// <summary>

        /// Field:UnitPrice 

        /// </summary>

        [DataMember]

        public virtual decimal UnitPrice { get; set; }

        

        #endregion   

        

        UnitsInStock#region UnitsInStock  

    

        /// <summary>

        /// Field:UnitsInStock 

        /// </summary>

        [DataMember]

        public virtual short UnitsInStock { get; set; }

        

        #endregion   

        

        UnitsOnOrder#region UnitsOnOrder  

    

        /// <summary>

        /// Field:UnitsOnOrder 

        /// </summary>

        [DataMember]

        public virtual short UnitsOnOrder { get; set; }

        

        #endregion   

        

        ReorderLevel#region ReorderLevel  

    

        /// <summary>

        /// Field:ReorderLevel 

        /// </summary>

        [DataMember]

        public virtual short ReorderLevel { get; set; }

        

        #endregion   

        

        Discontinued#region Discontinued  

    

        /// <summary>

        /// Field:Discontinued 

        /// </summary>

        [DataMember]

        public virtual bool Discontinued { get; set; }

        

        #endregion   

        

    

        Categories#region Categories 

        

        /// <summary>

        /// PrimaryKeyField:Categories 

        /// </summary>

        [DataMember]

        public virtual Categories CategoriesEntitiy { get; set; }

        

        #endregion

    }

    #endregion

}

 

<?xml version="1.0" encoding="utf-8" ?>



<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain.Entities">

    <class name="Domain.Entities.Products, Domain" table="Products">

        <id name="ProductID" column="ProductID" type="int" >

            <generator class="native" />

        </id>

    

        <property name="ProductName" column="ProductName" type="String" not-null="false"/>

        <property name="QuantityPerUnit" column="QuantityPerUnit" type="String" not-null="true"/>

        <property name="UnitPrice" column="UnitPrice" type="Decimal" not-null="true"/>

        <property name="UnitsInStock" column="UnitsInStock" type="Int16" not-null="true"/>

        <property name="UnitsOnOrder" column="UnitsOnOrder" type="Int16" not-null="true"/>

        <property name="ReorderLevel" column="ReorderLevel" type="Int16" not-null="true"/>

        <property name="Discontinued" column="Discontinued" type="Boolean" not-null="false"/>

    

    <many-to-one name="CategoriesEntitiy" column="CategoryID" class="Domain.Entities.Categories, Domain" />

    

    </class>

</hibernate-mapping>
复制代码
复制代码

/*

Class Library : Domain

Author        : Liudong

Create Date   : 2009-10-15

*/

using System;

using System.Collections;

using System.Collections.Generic;

using System.Runtime.Serialization;



namespace Domain.Entities

{

    #region Categories

    

    /// <summary>

    /// Entitiy:Categories object for NHibernate mapped table 

    /// </summary>

    [DataContract]

    public partial class Categories

    {

        #region CategoryID  

    

        /// <summary>

        /// Field:CategoryID 

        /// </summary>

        [DataMember]

        public virtual int? CategoryID { get; set; }

        

        #endregion   

        

        #region CategoryName  

    

        /// <summary>

        /// Field:CategoryName 

        /// </summary>

        [DataMember]

        public virtual string CategoryName { get; set; }

        

        #endregion   

        

        #region Description  

    

        /// <summary>

        /// Field:Description 

        /// </summary>

        [DataMember]

        public virtual string Description { get; set; }

        

        #endregion   

        

        #region Picture  

    

        /// <summary>

        /// Field:Picture 

        /// </summary>

        [DataMember]

        public virtual byte[] Picture { get; set; }

        

        #endregion   

        

    

        #region Products 

        

        /// <summary>

        /// ForeignKeyField:Products 

        /// </summary>

        [DataMember]

        public virtual IList<Products> ProductsList { get; set; }

        

        #endregion

    }

    #endregion

}





复制代码
复制代码
复制代码
/*

Class Library : Domain

Author        : Liudong

Create Date   : 2009-10-15

*/

using System;

using System.Collections;

using System.Collections.Generic;

using System.Runtime.Serialization;



namespace Domain.Entities

{

    #region Categories

    

    /// <summary>

    /// Entitiy:Categories object for NHibernate mapped table 

    /// </summary>

    [DataContract]

    public partial class Categories

    {

        #region CategoryID  

    

        /// <summary>

        /// Field:CategoryID 

        /// </summary>

        [DataMember]

        public virtual int? CategoryID { get; set; }

        

        #endregion   

        

        #region CategoryName  

    

        /// <summary>

        /// Field:CategoryName 

        /// </summary>

        [DataMember]

        public virtual string CategoryName { get; set; }

        

        #endregion   

        

        #region Description  

    

        /// <summary>

        /// Field:Description 

        /// </summary>

        [DataMember]

        public virtual string Description { get; set; }

        

        #endregion   

        

        #region Picture  

    

        /// <summary>

        /// Field:Picture 

        /// </summary>

        [DataMember]

        public virtual byte[] Picture { get; set; }

        

        #endregion   

        

    

        #region Products 

        

        /// <summary>

        /// ForeignKeyField:Products 

        /// </summary>

        [DataMember]

        public virtual IList<Products> ProductsList { get; set; }

        

        #endregion

    }

    #endregion

}

复制代码
<?xml version="1.0" encoding="utf-8" ?>



<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain.Entities">

    <class name="Domain.Entities.Categories, Domain" table="Categories">

        <id name="CategoryID" column="CategoryID" type="int" >

            <generator class="native" />

        </id>

        <property name="CategoryName" column="CategoryName" type="String" not-null="false"/>

        <property name="Description" column="Description" type="String" not-null="true"/>

        <property name="Picture" column="Picture" type="Byte[]" not-null="true"/>

    

    <bag name="ProductsList" inverse="true" lazy="true" cascade="all-delete-orphan">

      <key column="CategoryID" />

            <one-to-many  class="Domain.Entities.Products, Domain" />

        </bag>

    </class>

</hibernate-mapping>

      三、建立数据库访问层接口(IRepository)和其实现(Repository),随便引入程序集 (Antlr3.Runtime.dll,Castle.Core.dll,Castle.DynamicProxy2.dll,Iesi.Collections.dll,log4net.dll,NHibernate.ByteCode.Castle.dll,NHibernate.dll,NHibernate.Linq.dll)。

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace RepositoryDao

{

    public interface IRepository<T> where T : class

    {

        /// <summary>

        /// 返回IQueryable延迟加载集合

        /// </summary>

        /// <returns></returns>

        IQueryable<T> GetAll();

    }

}
复制代码
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using NHibernate;

using NHibernate.Linq;



namespace RepositoryDao

{

    public class Repository<T> : IRepository<T> where T : class

    {

        public IQueryable<T> GetAll()

        {

            ISession session = DBUtility.NHibernateHelper.GetCurrentSession();

            var result=from s in session.Linq<T>() select s;

            return result;

        }

    }

}
复制代码


      四、建立一个ASP.NET MVC应用程序,同样引入上述的程序集。在Global.asax配置相应的MapRoute

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

using System.Text;



namespace Linq2NHibernate

{

    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 

    // visit http://go.microsoft.com/?LinkId=9394801



    public class MvcApplication : System.Web.HttpApplication

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");



            routes.MapRoute(

                "GetPage",                                              // Route name

                "page/{pageId}/{pageSize}",                           // URL with parameters

                new { controller = "Home", action = "GetPage", pageId = 1, pageSize = 10 }  // Parameter defaults

            );



            routes.MapRoute(

                "GetOrderBy",                                              // Route name

                "order",                           // URL with parameters

                new { controller = "Home", action = "GetOrderBy" }  // Parameter defaults

            );



            routes.MapRoute(

                "GetWhere",                                              // Route name

                "where/{query}",                          // URL with parameters

                new { controller = "Home", action = "GetWhere", query = "C" }  // Parameter defaults

            );



            routes.MapRoute(

                "Default",                                              // Route name

                "{controller}/{action}/{id}",                           // URL with parameters

                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults

            );



        }



        protected void Application_Start()

        {

            RegisterRoutes(RouteTable.Routes);

            //log4net配置信息

            log4net.Config.XmlConfigurator.Configure();//.DOMConfigurator.Configure();

        }



        protected void Application_Error(object sender, EventArgs e)

        {

            log4net.ILog logger = log4net.LogManager.GetLogger("Logger");



            if (Server.GetLastError() != null)

            {

                Exception ex = Server.GetLastError().GetBaseException();

                StringBuilder sb = new StringBuilder();

                sb.Append(ex.Message);

                sb.Append("\r\nSOURCE: " + ex.Source);

                sb.Append("\r\nFORM: " + Request == null ? string.Empty : Request.Form.ToString());

                sb.Append("\r\nQUERYSTRING: " + Request == null ? string.Empty : Request.QueryString.ToString());

                sb.Append("\r\n引发当前异常的原因: " + ex.TargetSite);

                sb.Append("\r\n堆栈跟踪: " + ex.StackTrace);

                logger.Error(sb.ToString());

                Server.ClearError();

            }

        }

    }

}

在Web.config中配置hibernate和log4net

 

<configuration>

    <configSections>

        <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">

            <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">

                <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>

                <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">

                    <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>

                    <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>

                    <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>

                    <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>

                </sectionGroup>

            </sectionGroup>

        </sectionGroup>



    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

    <sectionGroup name="common">

      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>

    </sectionGroup>

    

        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>

    

    </configSections>

    <appSettings/>

    <connectionStrings>

        <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>

    </connectionStrings>

  

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

        <session-factory name="Linq2NHibernate">

            <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

            <property name="connection.connection_string">

        Server=(local);initial catalog=Northwind;Integrated Security=SSPI

      </property>

            <property name="adonet.batch_size">10</property>

            <property name="show_sql">false</property>

            <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>

            <property name="use_outer_join">true</property>

            <property name="command_timeout">60</property>

            <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>

            <!--2.1要配置延迟加载的代理 这里配置为Castle -->

            <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>

            <!--实体xml隐射文件的程序集-->

            <mapping assembly="Domain"/>

        </session-factory>

    </hibernate-configuration>



  <log4net debug="true">

    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">

      <param name="File" value="Logs\Application.log.txt"/>

      <param name="datePattern" value="MM-dd HH:mm"/>

      <param name="AppendToFile" value="true"/>

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>

      </layout>

    </appender>

    <appender name="HttpTraceAppender" type="log4net.Appender.ASPNetTraceAppender">

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>

      </layout>

    </appender>

    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>

      </layout>

    </appender>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">

      <param name="File" value="Logs/Log.txt"/>

      <param name="AppendToFile" value="true"/>

      <param name="MaxSizeRollBackups" value="10"/>

      <param name="MaximumFileSize" value="100K"/>

      <param name="RollingStyle" value="Size"/>

      <param name="StaticLogFileName" value="true"/>

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>

      </layout>

    </appender>

    <root>

      <level value="ALL"/>

      <appender-ref ref="RollingLogFileAppender"/>

    </root>

  </log4net>

  

    <system.web>

在HomeController加入如下方法

复制代码
using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using Domain.Entities;

using RepositoryDao;



namespace Linq2NHibernate.Controllers

{

    [HandleError]

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            ViewData["Message"] = "Welcome to ASP.NET MVC!";



            return View();

        }



        public ActionResult About()

        {

            return View();

        }



        /// <summary>

        /// 获取所有

        /// </summary>

        /// <returns></returns>

        public ActionResult GetAll()

        {

            IRepository<Products> dao = new Repository<Products>();

            var products = dao.GetAll();

            

            ViewData["List"] = products;

            return View();

        }



        /// <summary>

你可能感兴趣的:(Hibernate)