NHibernate相关:
- 09-08-25连贯NHibernate正式发布1.0候选版
- 09-08-17NHibernate中一对一关联的延迟加载
- 09-06-25NHibernate主键生成方式 Key Generator
- 09-06-25NHibernate操作Oracle的配置
- 09-06-25NHibernate更新部分字段
- 09-05-19NHibernate自定义数据类型
在微软发布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> /// 更加id获取对象 /// </summary> /// <param name="id"></param> /// <returns></returns> public ActionResult Get(int id) { IRepository<Products> dao = new Repository<Products>(); var products = dao.GetAll().Where(w => w.ProductID == id).First<Products>(); ViewData["Products"] = products; return View(); } /// <summary> /// 分页 /// </summary> /// <param name="pageId">页数</param> /// <param name="pageSize">每页数量</param> /// <returns></returns> public ActionResult GetPage(int pageId, int pageSize) { IRepository<Products> dao = new Repository<Products>(); var products = dao.GetAll().Skip((pageId - 1) * pageSize).Take(pageSize); ViewData["List"] = products; return View(); } /// <summary> /// 排序 /// </summary> /// <returns></returns> public ActionResult GetOrderBy() { IRepository<Products> dao = new Repository<Products>(); var products = dao.GetAll().OrderByDescending(o => o.ProductID); ViewData["List"] = products; return View(); } /// <summary> /// 条件查询 /// </summary> /// <param name="query"></param> /// <returns></returns> public ActionResult GetWhere(string query) { IRepository<Products> dao = new Repository<Products>(); var products = dao.GetAll().Where(w => w.ProductName.StartsWith(query)); ViewData["List"] = products; return View(); } } }
html页面
<table> <tr> <td>ProductID</td> <td>ProductName</td> <td>QuantityPerUnit</td> <td>UnitPrice</td> </tr> <% foreach (Domain.Entities.Products item in ViewData["List"] as IEnumerable<Domain.Entities.Products>) { %> <tr> <td><%= item.ProductID %></td> <td><%= item.ProductName %></td> <td><%= item.QuantityPerUnit %></td> <td><%= item.UnitPrice %></td> </tr> <%} %> </table>
类似增加View:GetOrderBy,GetPage,GetWhere
Linq相关:
- 10-10-02LINQ如何返回业务实体到上层逻辑
- 10-07-25LINQ中怎么使用LIKE方法?
- 10-03-19LINQ去除重复数据时报错"不支持用于查询运算符Distinct的重载",怎么解决?
- 10-03-19linq如何去除重复结果?
- 10-03-12Linq中的not in 语句应该怎么写?
来源:https://www.cnblogs.com/ctou45/archive/2013/02/06/2906089.html