10分钟搞定Linq to 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的类
















































































二、使用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
{
#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
}




















三、建立数据库访问层接口(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();
}
}
}


<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 to NHibernate就实现了。
发表于 2009年10月16日临晨2点20,广州。
作者:刘冬.NET
博客地址:http://www.cnblogs.com/GoodHelper/
欢迎转载,但须保留版权
分类:
NHibernate
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器