NHiberante从.net framework转移到.net standard(.net core 2.2)时遇到的坑及填坑
在.net framework中的创建session代码先贴一个
public class SessionBuilder
{
private static ISessionFactory _sessionFactory = null; public SessionBuilder()
{
if (_sessionFactory == null)
{
//创建ISessionFactory
_sessionFactory = GetSessionFactory();
}
} /// <summary>
/// 创建ISessionFactory
/// </summary>
/// <returns></returns>
public static ISessionFactory GetSessionFactory()
{
//HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); var mappers = new ModelMapper();
mappers.AddMappings(Assembly.GetExecutingAssembly().GetExportedTypes()); var cfg = new Configuration().Configure();
cfg.AddDeserializedMapping(mappers.CompileMappingForAllExplicitlyAddedEntities(), ""); return cfg.BuildSessionFactory();
} /// <summary>
/// 打开ISession
/// </summary>
/// <returns></returns>
public static ISession GetSession()
{
if (_sessionFactory == null || _sessionFactory.IsClosed)
{
//创建ISessionFactory
_sessionFactory = GetSessionFactory();
}
} #region 打开一个新的Session
public static ISession OpenSession()
{
return _sessionFactory.OpenSession(); }
#endregion }
与数据库的交互时,需要先在web.config配置(数据库为sql server)
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<!--NHibernate配置开始-->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<property name="show_sql">false</property>
<property name="connection.connection_string_name">ylsdai</property>
<property name="adonet.batch_size"></property>
<property name="generate_statistics">false</property>
<property name="format_sql">true</property>
<property name="command_timeout"></property>
<property name="current_session_context_class">web</property>
<!--<property name="cache.provider_class">NHibernate.Caches.SysCache2.SysCacheProvider,NHibernate.Caches.SysCache2</property>
<property name="cache.default_expiration"></property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>-->
</session-factory>
</hibernate-configuration>
<!--NHibernate配置结束-->
<connectionStrings>
<!--test_db-->
<!--<add name="ylsdai" connectionString="data source=0.0.0.1,111;database=test_db;uid=sa;pwd=123456" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
映射类
using NHibernate.Mapping.ByCode;
using NHibernate.Mapping.ByCode.Conformist; namespace ClassMapping
{
#region CityMap
public class CityMap : ClassMapping<City>
{
public CityMap()
{ SelectBeforeUpdate(true);
DynamicUpdate(true);
//Cache(p => p.Usage(CacheUsage.ReadWrite));
Id(p => p.CityId, map => map.Generator(Generators.Native));
Property(p => p.OldCityId);
Property(p => p.ParentId);
Property(p => p.CityName);
Property(p => p.EnCityName);
Property(p => p.CityImgUrl);
Property(p => p.LatLng);
Property(p => p.Keywords);
Property(p => p.IsRecommend);
Property(p => p.IsDepart);
Property(p => p.AreaId);
Property(p => p.CityContent);
}
}
#endregion
}
将实体写好,就可以进行实现了
但是在迁移到.net core的时候遇到的问题:
1. 创建Session,使用.net framework的方法将不可用
2.config中对于NHiberante的配置也读取不到
3.基于问题1,映射类也无法进行实现
好在是在.net core中有一个辅助的开源框架Fluent NHibernate,它可以帮我解决上面遇到的问题,但是在具体使用时也踩了不少坑
1.网上的文档基本都是映射类在xml中的,但是当实际项目在.cs文件中时,大量的文件映射从.cs文件迁到到.xml文件将变得特别繁琐
最后的解决办法,创建session方法中GetSessionFactory方法做以下修改
/// <summary>
/// 创建ISessionFactory
/// </summary>
/// <returns></returns>
public static ISessionFactory GetSessionFactory()
{
var assemblyName = Assembly.Load("ClassMapping"); NHibernate.Cfg.Configuration setCfg(NHibernate.Cfg.Configuration c)
{
c.Properties.Add("show_sql", "true");
c.Properties.Add("adonet.batch_size", "");
c.Properties.Add("generate_statistics", "false");
c.Properties.Add("format_sql", "true");
c.Properties.Add("command_timeout", "");
c.Properties.Add("current_session_context_class", "web");
return c;
} return Fluently.Configure().Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2012.ConnectionString("Server=0.0.0.1,111;Database=test_db;Uid=sa;Pwd=123456;"))
.Mappings(m => m.FluentMappings.AddFromAssembly(assemblyName))
.ExposeConfiguration(c => new SchemaUpdate(c).Execute(true, false))
.ExposeConfiguration(c => setCfg(c))
//.ExposeConfiguration(f => f.SetInterceptor(new SqlStatementInterceptor()))
.BuildSessionFactory(); }
其中映射类的引入在
.Mappings(m => m.FluentMappings.AddFromAssembly(assemblyName))
这句话,是将命名空间引入,所以具体映射类可以重新新建一个项目,名字就叫做ClassMapping,具体的映射类做以下修改
using Entity;
using FluentNHibernate.Mapping; namespace ClassMapping
{
#region CityMap
public class CityMap : ClassMap<City>
{
public CityMap()
{
Table("City"); //SelectBeforeUpdate(true);
//DynamicUpdate(true);
//Cache(p => p.Usage(CacheUsage.ReadWrite));
Id(p => p.CityId);
Map(p => p.OldCityId);
Map(p => p.ParentId);
Map(p => p.CityName);
Map(p => p.EnCityName);
Map(p => p.CityImgUrl);
Map(p => p.LatLng);
Map(p => p.Keywords);
Map(p => p.IsRecommend);
Map(p => p.IsDepart);
Map(p => p.AreaId);
Map(p => p.CityContent);
}
}
#endregion }
在迁移过程中会碰到映射关系的迁移
以前的版本中为
OneToOne(p => p.City, map =>
{
map.Cascade(Cascade.All);
map.Lazy(LazyRelation.Proxy);
});//一对一 ManyToOne(p => p.Province, map => map.Column("ProvinceId"));//多对一 Bag(p => p.Counties, map =>
{
map.Key(k => k.Column("CountyId"));
map.OrderBy(k => k.SortId);
}, rel => rel.OneToMany());//一对多
.net core版本中对应为
HasOne(p => p.City).Cascade.All().LazyLoad();//一对一
//References<Province>(r => r.Province).Column("ProvinceId").ForeignKey("ProvinceId").Cascade.None();//多对一,在实际运用中会出现问题
HasMany(p => p.Counties).KeyColumn("CountyId").OrderBy("CountyId").LazyLoad();//一对多
city实体
[Serializable]
public class City : BaseEntity
{
/// <summary>
/// CityId
/// </summary>
public virtual int CityId { get; set; } /// <summary>
/// Version
/// </summary>
public virtual int Version { get; set; } /// <summary>
/// OldCityId
/// </summary>
public virtual int OldCityId { get; set; } /// <summary>
/// ParentId
/// </summary>
public virtual int ParentId { get; set; } /// <summary>
/// 城市名称
/// </summary>
public virtual string CityName { get; set; } /// <summary>
/// 城市英文名称
/// </summary>
public virtual string EnCityName { get; set; } /// <summary>
/// CityImgUrl
/// </summary>
public virtual string CityImgUrl { get; set; } /// <summary>
/// 经纬度
/// </summary>
public virtual string LatLng { get; set; } /// <summary>
/// 关键字
/// </summary>
public virtual string Keywords { get; set; } /// <summary>
/// 是否推荐
/// </summary>
public virtual bool IsRecommend { get; set; } /// <summary>
/// IsDepart
/// </summary>
public virtual bool IsDepart { get; set; } /// <summary>
/// 航区
/// </summary>
public virtual int AreaId { get; set; } /// <summary>
/// 城市介绍
/// </summary>
public virtual string CityContent { get; set; } }
下面是操作session,进行数据库调用的方法
/// <summary>
/// Hibernate操作Helper
/// </summary>
/// <typeparam name="T"></typeparam>
public class DbHelper<T> where T : BaseEntity
{
private readonly ISession _session = SessionBuilder.GetSession();
//protected static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public DbHelper() { } public DbHelper(ISession session)
{
_session = session;
} #region 获取一个实体
/// <summary>
/// 获取一个实体(一级缓存)
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public T Load(int id)
{
return _session.Load<T>(id);
} #endregion #region 获取一个实体(缓存)
/// <summary>
/// 获取一个实体(二级缓存)
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public T Get(int id)
{
return _session.Get<T>(id);
}
#endregion #region 销毁一个实体
/// <summary>
/// 销毁一个实体
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public void Evict(object obj)
{
_session.Evict(obj);
}
#endregion /// <summary>
/// 根据SQL语句获取
/// </summary>
/// <param name="sql"></param>
public ISQLQuery CreateSqlQuery(string sql)
{
return _session.CreateSQLQuery(sql);
} /// <summary>
/// 获取集合
/// </summary>
/// <param name="hql"></param>
/// <returns></returns>
public ICriteria GetCriteria(string hql)
{
return _session.CreateCriteria(hql);
} #region 获取全部数据
/// <summary>
/// 获取全部数据
/// </summary>
/// <param name="cacheable">是否缓存</param>
/// <returns></returns>
public IEnumerable<T> GetAll(bool cacheable)
{
var ic = _session.CreateCriteria(typeof(T));
IEnumerable<T> list = ic.SetCacheable(cacheable).List<T>() ?? new List<T>();
return list;
}
#endregion #region 插入或者更新数据
/// <summary>
/// 插入数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Save(T entity)
{
var id = ;
var session = this._session;
ITransaction tan = session.BeginTransaction(); try
{
entity = session.Merge(entity);
}
catch (Exception e)
{
//Log.DebugFormat($"Save124,Exception:{e.Message},entity:{JsonConvert.SerializeObject(entity)}");
} try
{
tan.Begin();
id = (int)session.Save(entity);
session.Flush();
tan.Commit();
}
catch (Exception e)
{
//Log.DebugFormat($"Save136,Exception:{e.Message},entity:{JsonConvert.SerializeObject(entity)}");
tan.Rollback();
throw;
} return id;
}
#endregion #region 更新数据
/// <summary>
/// 更新数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Update(T entity)
{
int result = ;
ITransaction tan = _session.BeginTransaction();
var session = this._session;
//entity = (T)_session.Merge(entity);
try
{
entity = session.Merge(entity);
}
catch (Exception e)
{
//Log.DebugFormat($"Update163,Exception:{e.Message},entity:{JsonConvert.SerializeObject(entity)}");
}
try
{
tan.Begin();
_session.Update(entity);
_session.Flush();
tan.Commit();
result++;
}
catch (Exception e)
{
//Log.DebugFormat($"Update175,Exception:{e.Message},entity:{JsonConvert.SerializeObject(entity)}");
tan.Rollback();
throw;
}
return result;
}
#endregion #region 删除一条数据
/// <summary>
/// 删除一条数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int DeleteModelById(int id)
{
int result = ;
object item = Get(id);
//ITransaction tan = _session.BeginTransaction();
try
{
//tan.Begin();
_session.Delete(item);
_session.Flush();
//tan.Commit();
result++;
}
catch (Exception)
{
//tan.Rollback();
throw;
} return result;
}
#endregion #region 删除一个实体对象
/// <summary>
/// 删除一个实体对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int DeleteModel(BaseEntity entity)
{
var result = ;
//ITransaction tan = _session.BeginTransaction();
try
{
//tan.Begin();
_session.Delete(entity);
_session.Flush();
//tan.Commit();
result++;
}
catch (Exception)
{
//tan.Rollback();
throw;
}
return result;
}
#endregion /// <summary>
/// 根据SQL语句删除
/// </summary>
/// <param name="sql"></param>
public void DeleteList(string sql)
{
_session.CreateSQLQuery(sql).UniqueResult();
} /// <summary>
/// 删除泛型集合
/// </summary>
/// <param name="models"></param>
public void DeleteList(IList<T> models)
{
foreach (var model in models)
{
DeleteModel(model);
}
} public bool IsExist(Expression<Func<T, bool>> keyWhere)
{
var ss = _session.QueryOver<T>().Where(keyWhere);
return ss.RowCount() > ;
} #region GetQuery
/// <summary>
/// GetQuery
/// </summary>
/// <returns></returns>
public IQueryable<T> GetQuery()
{
try
{
return _session.Query<T>();
}
catch (Exception e)
{
var session = SessionBuilder.GetSession();
return session.Query<T>();
}
}
#endregion #region GetQueryOver
/// <summary>
/// GetQueryOver
/// </summary>
/// <returns></returns>
public IQueryOver<T, T> GetQueryOver(Expression<Func<T, bool>> keyWhere)
{
return _session.QueryOver<T>().Where(keyWhere);
} #endregion #region GetQueryOver
/// <summary>
/// GetQueryOver
/// </summary>
/// <returns></returns>
public IQueryOver<T, T> GetQueryOver()
{
return _session.QueryOver<T>();
}
#endregion #region 获取集合ByHql
/// <summary>
/// 获取集合ByHql
/// </summary>
/// <param name="strHql"></param>
/// <returns></returns>
public IQuery GetQueryByHql(string strHql)
{
return _session.CreateQuery(strHql);
}
#endregion #region 获取集合BySql
/// <summary>
/// 获取集合BySql
/// </summary>
/// <param name="strSql"></param>
/// <returns></returns>
public IQuery GetQueryBySql(string strSql)
{
return _session.CreateSQLQuery(strSql);
}
#endregion
}
NHiberante从.net framework转移到.net standard(.net core 2.2)时遇到的坑及填坑的更多相关文章
- html标签从.net framework转移到.net standard(.net core 2.2)时遇到的坑及填坑
在原来的.net framework mvc中html的标签可以使用下面的方法 <select class="form-control" id="categoryi ...
- org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start()
http://freestyle21.cn 不知什么时候,启动eclipse的时候就一直不行,说是an error ..我查了下log 报错:org.osgi.framework.BundleExce ...
- .Net Core vs .Net Framework 如何为一个应用程序选择一个运行时(翻译)
.Net Core是下一件大事吗?我已经使用了一段时间了,我倾向认为它是.事实上,我们推测,在2018年,对这项技术熟练的开发人员将会有巨大的需求.但是它和.Net Framework的区别是什么?你 ...
- 填坑 - 使用Entity Framework 6 + Sqlite进行DB first开发
Sqlite团队也是渣啊,到第6代了还不支持Code First. 1.安装运行环境和组件 .安装SQLite的Visual Studio设计器支持 只有安装了它,在[新建ADO.NET实体数据模型] ...
- MVC5项目转.Net Core 2.2学习与填坑记录(1)
流程都是自己摸索,错误地方随便指正... 老项目过于臃肿,并且所有请求都是提交到一个api中,这样当api挂掉的时候,基本所有的项目都瘫痪掉了. 在4月底的时候,下决心将项目用微服务进行重写,刚开始的 ...
- 微信Android客户端架构演进之路
这是一个典型的Android应用在从小到大的成长过程中的“踩坑”与“填坑”的历史.互联网的变化速度如此之快,1年的时间里,可以发生翻天覆地的变化.今天在这里,重新和大家回顾微信客户端架构的演进过程,以 ...
- 转:微信Android客户端架构演进之路
转自: http://www.infoq.com/cn/articles/wechat-android-app-architecture 微信Android客户端架构演进之路 作者 赵原 发布于 20 ...
- 为何某些公司不允许使用C++ STL?
说几个STL的缺点吧,虽然都是在比较极端的情况下出现,但是对于一些大项目还是会遇到的 1. 代码膨胀问题每一个实例化过的模板类,都会膨胀出一份独立的代码,比如std::vector<std::s ...
- .Net Core建站(3):搭建三层架构
啊,终于到写三层架构的时候了,老实说,我都不知道自己这个算不算三层架构,姑且就当它是吧,具体属于哪一个体系,希望有大佬指点一下(^o^)/ 不晓得有人注意到没有,我写了三篇博客,然后就改了三次标题ヽ( ...
随机推荐
- 使用PHP实现查找附近的人
https://zhuanlan.zhihu.com/p/31380780 LBS(基于位置的服务) 查找附近的人有个更大的专有名词叫做LBS(基于位置的服务),LBS是指是指通过电信移动运营商的无线 ...
- osgViewer:: Viewer::advance() osg多线程与智能指针
void ViewerBase::frame(double simulationTime) { if (_done) return; // OSG_NOTICE<<std::endl< ...
- SSM配置基于注解AOP
pom.xml <dependency> <groupId>org.springframework</groupId> <artifactId>spri ...
- python常见面试集合
Python面试题目一.Python1. python的多进程与多线程的运行机制是什么?有什么区别?分别在什么情况下用?2. Python的装饰器的原理是什么,在什么情况会用到装饰器.请手写Pytho ...
- mysql的root用户无法给普通用户授权问题处理
1.查看Grant_priv是Y还是N 执行下面 select * from mysql.user where User='root' and Host='%'\G; 下图查看结果为Grant_pri ...
- node.js写巨大的xlsx
一般用node-xlsx写xlsx文件的话局要把数据全部放在内存里面再写到文件里,如果文件很大的话就会导致内存吃不消. 可以使用PySpreadsheet这个npm库,他支持写很大的文件. PySpr ...
- [c++]C++关键字之friend
re 1. C++关键字之friend; end 希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬.---GOOD---
- Sybase数据库网页数据维护工具
Sybase是优秀的数据库产品,在银行,政务等行业广泛使用, 现在TreeSoft数据库管理系统已支持Sybase了,直接在浏览器中就可以操作查看Sybase数据了,十分方便. Tree ...
- 【数据库开发】在Windows上利用C++开发MySQL的初步
[数据库开发]在Windows上利用C++开发MySQL的初步 标签(空格分隔): [编程开发] Windows上在上面配置环境的基础上开展一个小demo链接数据库,没想到中间也出现了这么多的问题,简 ...
- Andrew Ng机器学习课程16
Andrew Ng机器学习课程16 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:主要介绍了ICA算法,并利用最大似然估计和随机梯度上升算法进行求解, ...