失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现

NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现

时间:2020-03-17 20:40:00

相关推荐

NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现

关于NHibernate的ORM映射可以通过Hbm映射文件来完成,代码生成工具使得这一步骤变得简化;而NHibernate3.2版本集成Mapping-By-Code(代码映射),不同于其他映射方式,具体可以参考李永京博客(NHibernate剖析:Mapping篇之Mapping-By-Code),此处不再赘述;Mapping-By-Code采用手动配置实体映射,顾名思义会增加程序代码编写量,而且数据库表关系映射(ont-to-many, many-to-one,many-to-many)编写比较复杂,所以我摒弃这种方式而采用了Mindscape NHibernate Model Designer设计工具。为此,首先介绍一下NHibernate数据访问层,Web.config文件配置、NHibernateConfiguration类和Session Manager类。

Web.config 隐藏行号 复制代码 ?

<appSettings>

<add key="ClientValidationEnabled" value="true"/>

<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

<add key="TESZConnectionString" value="User id=sa;Password=sql123!!;data source=localhost;persist security info=True;initial catalog=TESZ_NEW;"/>

</appSettings>

Web.config是采用appSettings来设置数据库connection string,而非NHiberate标准配置。

NHibernateCfg.cs 隐藏行号 复制代码 ?

public static class NHibernateCfg

{

private static string _ConnectionString;

public static Configuration GetConfiguration()

{

_ConnectionString = System.Configuration.ConfigurationManager.AppSettings["TESZConnectionString"].ToString();

var configure = new Configuration();

configure.SessionFactoryName("TESZ_NEW");

configure.DataBaseIntegration(db =>

{

db.Dialect<MsSqlDialect>();

db.Driver<SqlClientDriver>();

db.ConnectionString = _ConnectionString;

});

ApplyConfiguration(configure);

return configure;

}

public static void ApplyConfiguration(Configuration configuration)

{

configuration.AddXml(Location_Country.MappingXml.ToString());

configuration.AddXml(Location_StateProvince.MappingXml.ToString());

configuration.AddXml(Location_City.MappingXml.ToString());

configuration.AddXml(Common_Date.MappingXml.ToString());

configuration.AddXml(System_Purview.MappingXml.ToString());

configuration.AddAssembly(typeof(NHibernateCfg).Assembly);

}

}

此处在NHibernateCfg类中进行数据库连接属性的配置,并把由Mindscape NHibernate Model Designer工具生成的实体类中的MappingXml配置给Configuration,来进行ORM映射。

SessionManager.cs 隐藏行号 复制代码 ?

/// <summary>

/// 使用 NHibernate 操作数据库的Session

/// </summary>

public sealed class SessionManager

{

private const string CurrentSessionKey = "nhibernate.current_session";

private static readonly ISessionFactory sessionFactory;

private static Configuration conf = null;

private static ModelMapper mapper = null;

static SessionManager()

{

mapper = new ModelMapper();

if (sessionFactory == null)

{

conf = NHibernateCfg.GetConfiguration();

sessionFactory = conf.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;

}

else

{

currentSession = sessionFactory.OpenSession();

}

return currentSession;

}

public static void CreateDataTable()

{

//配置数据库a

SchemaMetadataUpdater.QuoteTableAndColumns(conf);

//创建数据库

new SchemaExport(conf).Create(false, true);

}

public static void DropDataTable()

{

//配置数据库

SchemaMetadataUpdater.QuoteTableAndColumns(conf);

//删除数据库

new SchemaExport(conf).Drop(false, true);

}

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();

}

}

}

以上是NHibernate Session管理类。

接着就该讲如何通过Mindscape NHibernate Model Designer工具生成实体类了。具体方法是:选择新建项,在“已安装的模版”的数据分类下选择NHibernateModel,然后从“服务器资源管理器”中拖拽表至Mindscape设计器中,并可以通过NHibernateModel工具栏的Model->Entities->实体类的属性进行实体类的更名。生成的实体类如下图:

Location_Country.cs 隐藏行号 复制代码 ?

[piler.GeneratedCode("NHibernateModelGenerator", "1.0.0.0")]

public partial class Location_Country

{

public virtual int CountryId { get; set; }

public virtual string CountryCode1 { get; set; }

public virtual string CountryCode2 { get; set; }

public virtual System.Nullable<System.DateTime> ModifiedDate { get; set; }

public virtual string ModifiedBy { get; set; }

public virtual string CountryDialCode { get; set; }

public virtual string CountryName { get; set; }

private IList<Location_StateProvince> _locationStateProvinces = new List<Location_StateProvince>();

public virtual IList<Location_StateProvince> LocationStateProvinces

{

get { return _locationStateProvinces; }

set { _locationStateProvinces = value; }

}

static partial void CustomizeMappingDocument(System.Xml.Linq.XDocument mappingDocument);

public static System.Xml.Linq.XDocument MappingXml

{

get

{

var mappingDocument = System.Xml.Linq.XDocument.Parse(@"<?xml version='1.0' encoding='utf-8' ?>

<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'

assembly='" + typeof(Location_Country).Assembly.GetName().Name + @"'

namespace='TESZ.Data.Model'

>

<class name='Location_Country'

table='`Location_Country`'

>

<id name='CountryId'

column='`CountryId`'

>

<generator class='identity'>

</generator>

</id>

<property name='CountryCode1'

column='`CountryCode1`'

/>

<property name='CountryCode2'

column='`CountryCode2`'

/>

<property name='ModifiedDate'

column='`ModifiedDate`'

/>

<property name='ModifiedBy'

column='`ModifiedBy`'

/>

<property name='CountryDialCode'

column='`CountryDialCode`'

/>

<property name='CountryName'

column='`CountryName`'

/>

<bag name='LocationStateProvinces'

inverse='true'

>

<key column='`CountryId`' />

<one-to-many class='Location_StateProvince' />

</bag>

</class>

</hibernate-mapping>");

CustomizeMappingDocument(mappingDocument);

return mappingDocument;

}

}

}

此处请注意一下三项(以上实体类已经经过修改):

1.自动生成的实体类文件中,需要删除ConfigurationHelper类,因为之前在NHibernateCfg中已经配置MappingXml;

2.实体类中的internal static System.Xml.Linq.XDocument MappingXml的internal需改为public,否则NHibernateCfg的configuration.AddXml(Location_Country.MappingXml.ToString());会报错;

3.如果数据表有one-to-many关系,则必有many-to-one关系,MappingXml中会自动生成;比如<many-to-one name='Country' class='Location_Country' column='`CountryId`' />,则需要在其中添加lazy='false' 属性,否则实体类Location_StateProvince通过mant-to-one关系访问实体Location_Country时会抛出异常;

4.如果数据表结构发生变化,可以在Mindscape设计器中以Update Model from Database来更新实体类,之后还要重复以上三个步骤。

如需自动生成one-to-many和many-to-one关系,则在进行数据库创建时,要配置数据表对应关系,如下图:

数据表关系设计

如此,就完成了实体类的编写。

最后简单讲一下数据访问接口和接口实现,在这儿我就不仔细说了,直接贴代码吧!

ILocation_CountryRepository.cs 隐藏行号 复制代码 ?

public interface ILocation_CountryRepository

{

IList<Location_Country> FindAll();

IList<Location_Country> FindIndistinct(Country_Query_Index country_Query_Index , object o);

bool Create(Location_Country location_Country);

bool Update(Location_Country location_Country);

bool Delete(Location_Country location_Country);

Location_Country FindOne(Country_Query_Index country_Query_Index, object o);

}

通过QueryOver和Lambda表达式进行数据查询

Location_CountryRepository.cs 隐藏行号 复制代码 ?

public class Location_CountryRepository : ILocation_CountryRepository

{

public Location_CountryRepository()

{

}

public IList<Location_Country> FindAll()

{

using (var session = SessionManager.GetCurrentSession())

{

var query = session.QueryOver<Location_Country>()

.OrderBy(p => p.CountryId).Asc

.List();

return query;

}

}

//模糊查询

public IList<Location_Country> FindIndistinct(Country_Query_Index country_Query_Index, object o)

{

using (var session = SessionManager.GetCurrentSession())

{

IList<Location_Country> query=null;

switch (country_Query_Index)

{

case Country_Query_Index.CountryName:

{

query = session.QueryOver<Location_Country>()

.WhereRestrictionOn(k => k.CountryName).IsLike(o)

.OrderBy(p => p.CountryId).Asc

.List();

break;

}

case Country_Query_Index.Code1:

{

query = session.QueryOver<Location_Country>()

.WhereRestrictionOn(k => k.CountryCode1).IsLike(o)

.OrderBy(p => p.CountryId).Asc

.List();

break;

}

case Country_Query_Index.Code2:

{

query = session.QueryOver<Location_Country>()

.WhereRestrictionOn(k => k.CountryCode2).IsLike(o)

.OrderBy(p => p.CountryId).Asc

.List();

break;

}

case Country_Query_Index.DialCode:

{

query = session.QueryOver<Location_Country>()

.WhereRestrictionOn(k => k.CountryDialCode).IsLike(o)

.OrderBy(p => p.CountryId).Asc

.List();

break;

}

}

return query;

}

}

public Location_Country FindOne(Country_Query_Index country_Query_Index,object o)

{

using (var session = SessionManager.GetCurrentSession())

{

Location_Country query = null;

switch (country_Query_Index)

{

case Country_Query_Index.CountryId:

{

query = session.QueryOver<Location_Country>()

.Where(p => p.CountryId==(int)o)

.SingleOrDefault();

break;

}

case Country_Query_Index.CountryName:

{

query = session.QueryOver<Location_Country>()

.Where(p => p.CountryName == o.ToString())

.SingleOrDefault();

break;

}

case Country_Query_Index.Code1:

{

query = session.QueryOver<Location_Country>()

.Where(p => p.CountryCode1 == o.ToString())

.SingleOrDefault();

break;

}

case Country_Query_Index.Code2:

{

query = session.QueryOver<Location_Country>()

.Where(p => p.CountryCode2 == o.ToString())

.SingleOrDefault();

break;

}

case Country_Query_Index.DialCode:

{

query = session.QueryOver<Location_Country>()

.Where(p => p.CountryDialCode == o.ToString())

.SingleOrDefault();

break;

}

}

return query;

}

}

public bool Create(Location_Country model)

{

bool result = false;

using (var session = SessionManager.GetCurrentSession())

{

using (var trans = session.BeginTransaction())

{

session.Save(model);

mit();

result = true;

}

}

return result;

}

public bool Update(Location_Country model)

{

bool result = false;

using (var session = SessionManager.GetCurrentSession())

{

using (var trans = session.BeginTransaction())

{

session.Update(model);

mit();

result = true;

}

}

return result;

}

public bool Delete(Location_Country model)

{

bool result = false;

using (var session = SessionManager.GetCurrentSession())

{

using (var trans = session.BeginTransaction())

{

session.Delete(model);

mit();

result = true;

}

}

return result;

}

}

如果觉得《NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。