SqlServer与MongoDB结合使用NHibernate
程序员文章站
2022-06-25 09:48:00
本文实例为大家分享了sqlserver与mongodb结合使用nhibernate的代码,供大家参考,具体内容如下
program.cs代码内容:
cl...
本文实例为大家分享了sqlserver与mongodb结合使用nhibernate的代码,供大家参考,具体内容如下
program.cs代码内容:
class program { private const string sqlserverconnectionstring = @"data source=.;initial catalog=sqlwithmongo;persist security info=true;user id=sa;password=123456"; private const string mongoconnectionstring = "mongodb://localhost:27017"; private const int numberofnodes = 1000; private static void main(string[] args) { console.writeline("clearing database..."); cleardatabases(); initer.init(sqlserverconnectionstring, mongoconnectionstring); console.writeline("completed"); console.writeline("creating nodes..."); //创建sqlserver的node节点 createnodes(); console.writeline("completed"); console.writeline("linking nodes..."); long milliseconds1 = linksqlnodes(); //创建sqlserver的linknode节点 console.writeline("sql : " + milliseconds1); long milliseconds2 = linkmongonodes(); //同时创建node,linknode节点 console.writeline("mongo : " + milliseconds2); console.writeline("completed"); console.writeline("fetching nodes..."); long milliseconds3 = fetchsqlnodes(); //取出sqlserver节点数据 console.writeline("sql : " + milliseconds3); long milliseconds4 = fetchmongonodes(); //取出mongodb节点数据 console.writeline("mongo : " + milliseconds4); console.writeline("completed"); console.readkey(); } private static long fetchmongonodes() { var stopwatch = new stopwatch(); stopwatch.start(); for (int i = 0; i < numberofnodes; i++) { using (var unitofwork = new unitofwork()) { var repository = new mongonoderepository(unitofwork); mongonode node = repository.getbyid(i + 1); ireadonlylist<nodelink> links = node.links; } } stopwatch.stop(); return stopwatch.elapsedmilliseconds; } private static long fetchsqlnodes() { var stopwatch = new stopwatch(); stopwatch.start(); for (int i = 0; i < numberofnodes; i++) { using (var unitofwork = new unitofwork()) { var repository = new noderepository(unitofwork); node node = repository.getbyid(i + 1); ireadonlylist<node> links = node.links; } } stopwatch.stop(); return stopwatch.elapsedmilliseconds; } private static long linksqlnodes() { var stopwatch = new stopwatch(); stopwatch.start(); using (var unitofwork = new unitofwork()) { var repository = new noderepository(unitofwork); ilist<node> nodes = repository.getall(); foreach (node node1 in nodes) { foreach (node node2 in nodes) { node1.addlink(node2); } } unitofwork.commit(); } stopwatch.stop(); return stopwatch.elapsedmilliseconds; } private static long linkmongonodes() { var stopwatch = new stopwatch(); stopwatch.start(); using (var unitofwork = new unitofwork()) { var repository = new mongonoderepository(unitofwork); ilist<mongonode> nodes = repository.getall(); foreach (mongonode node1 in nodes) { foreach (mongonode node2 in nodes) { node1.addlink(node2); } } unitofwork.commit(); } stopwatch.stop(); return stopwatch.elapsedmilliseconds; } private static void createnodes() { using (var unitofwork = new unitofwork()) { var repository = new noderepository(unitofwork); for (int i = 0; i < numberofnodes; i++) { var node = new node("node " + (i + 1)); //实例化 构造函数初始化name repository.save(node); } unitofwork.commit(); } using (var unitofwork = new unitofwork()) { var repository = new mongonoderepository(unitofwork); for (int i = 0; i < numberofnodes; i++) { var node = new mongonode("node " + (i + 1)); repository.save(node); } unitofwork.commit(); } } //清空数据 private static void cleardatabases() { new mongoclient(mongoconnectionstring) .getdatabase("sqlwithmongo") .dropcollectionasync("links") .wait(); string query = "delete from [dbo].[mongonode];" + "delete from [dbo].[node_node];" + "delete from [dbo].[node];" + "update [dbo].[ids] set [nexthigh] = 0"; using (var connection = new sqlconnection(sqlserverconnectionstring)) { var command = new sqlcommand(query, connection) { commandtype = commandtype.text }; connection.open(); command.executenonquery(); } } }
相关辅助类代码如下:
public static class initer { public static void init(string sqlserverconnectionstring, string mongoconnectionstring) { //sqlserver初始化 sessionfactory.init(sqlserverconnectionstring); //mongodb初始化 nodelinkrepository.init(mongoconnectionstring); } }
public static class sessionfactory //工厂 { private static isessionfactory _factory; internal static isession opensession() { return _factory.opensession(new interceptor()); } internal static void init(string connectionstring) { _factory = buildsessionfactory(connectionstring); } private static isessionfactory buildsessionfactory(string connectionstring) { //用编程的方式进行配置,让你能更好的理解,不需要编写复杂的映射文件,它能完全替换nhibernate的映射文件,让你在映射的时候能使用c#的强类型方式。 fluentconfiguration configuration = fluently.configure() .database(mssqlconfiguration.mssql2012.connectionstring(connectionstring)) .mappings(m => m.fluentmappings.addfromassembly(assembly.getexecutingassembly())) .exposeconfiguration(x => { x.eventlisteners.postloadeventlisteners = new ipostloadeventlistener[] { new eventlistener() }; }); return configuration.buildsessionfactory(); } }
internal class nodelinkrepository //仓库 repository模式 { private static imongocollection<nodelinks> _collection; public ilist<nodelink> getlinks(int nodeid) { nodelinks links = _collection.find(x => x.id == nodeid).singleordefaultasync().result; if (links == null) return new nodelink[0]; return links.links; } public task savelinks(int nodeid, ienumerable<nodelink> links) { var nodelinks = new nodelinks(nodeid, links); var updateoptions = new updateoptions { isupsert = true }; return _collection.replaceoneasync(x => x.id == nodeid, nodelinks, updateoptions); } internal static void init(string connectionstring) { var client = new mongoclient(connectionstring); imongodatabase database = client.getdatabase("sqlwithmongo"); var collectionsettings = new mongocollectionsettings { writeconcern = new writeconcern(1) }; _collection = database.getcollection<nodelinks>("links", collectionsettings); } private class nodelinks { public int id { get; private set; } public list<nodelink> links { get; private set; } public nodelinks(int nodeid, ienumerable<nodelink> links) { id = nodeid; links = new list<nodelink>(); links.addrange(links); } } }
public class noderepository { private readonly unitofwork _unitofwork; public noderepository(unitofwork unitofwork) { _unitofwork = unitofwork; } public node getbyid(int id) { return _unitofwork.get<node>(id); } public ilist<node> getall() { return _unitofwork.query<node>() .tolist(); } public void save(node mongonode) { _unitofwork.saveorupdate(mongonode); } }
public class mongonoderepository { private readonly unitofwork _unitofwork; public mongonoderepository(unitofwork unitofwork) { _unitofwork = unitofwork; } public mongonode getbyid(int id) { return _unitofwork.get<mongonode>(id); } public void save(mongonode mongonode) { _unitofwork.saveorupdate(mongonode); } public ilist<mongonode> getall() { return _unitofwork.query<mongonode>() .tolist(); } }
模型层数据:
node.cs,nodemap.cs类代码如下:
public class node { public virtual int id { get; protected set; } public virtual string name { get; protected set; } protected virtual iset<node> linksinternal { get; set; } public virtual ireadonlylist<node> links { get { return linksinternal.tolist(); } } protected node() { linksinternal = new hashset<node>(); } public node(string name) : this() { name = name; } public virtual void addlink(node node) { linksinternal.add(node); node.linksinternal.add(this); } }
public class nodemap : classmap<node> //fluentnhibernate.mapping.classlikemapbase<t> { public nodemap() { id(x => x.id, "nodeid").generatedby.hilo("[dbo].[ids]", "nexthigh", "10", "entityname = 'node'"); map(x => x.name).not.nullable(); hasmanytomany<node>(reveal.member<node>("linksinternal")) .asset() .table("node_node") .parentkeycolumn("nodeid1") .childkeycolumn("nodeid2"); } }
mongonode.cs和mongonodemap.cs的代码如下:
public class mongonode { public virtual int id { get; protected set; } public virtual string name { get; protected set; } protected virtual hashset<nodelink> linksinternal { get; set; } public virtual ireadonlylist<nodelink> links { get { return linksinternal.tolist(); } } protected mongonode() { linksinternal = new hashset<nodelink>(); } public mongonode(string name) : this() { name = name; } public virtual void addlink(mongonode mongonode) { linksinternal.add(new nodelink(mongonode.id, mongonode.name)); mongonode.linksinternal.add(new nodelink(id, name)); } }
public class mongonodemap : classmap<mongonode> //fluentnhibernate中的类继承 { public mongonodemap() { id(x => x.id, "mongonodeid").generatedby.hilo("[dbo].[ids]", "nexthigh", "10", "entityname = 'mongonode'"); map(x => x.name).not.nullable(); } }
utils层的类:
eventlistener.cs内容:
internal class eventlistener : ipostloadeventlistener //nhibernate.event继承 { public void onpostload(postloadevent ev) { var networknode = ev.entity as mongonode; if (networknode == null) return; var repository = new nodelinkrepository(); ilist<nodelink> linksfrommongo = repository.getlinks(networknode.id); hashset<nodelink> links = (hashset<nodelink>)networknode .gettype() .getproperty("linksinternal", bindingflags.nonpublic | bindingflags.instance) .getvalue(networknode); links.unionwith(linksfrommongo); } }
internal class interceptor : emptyinterceptor //nhibernate中的类 { public override void postflush(icollection entities) { ienumerable<mongonode> nodes = entities.oftype<mongonode>(); if (!nodes.any()) return; var repository = new nodelinkrepository(); task[] tasks = nodes.select(x => repository.savelinks(x.id, x.links)).toarray(); task.waitall(tasks); } }
unitofwork.cs代码:
public class unitofwork : idisposable { private readonly isession _session; private readonly itransaction _transaction; private bool _isalive = true; private bool _iscommitted; public unitofwork() { _session = sessionfactory.opensession(); _transaction = _session.begintransaction(isolationlevel.readcommitted); } public void dispose() { if (!_isalive) return; _isalive = false; try { if (_iscommitted) { _transaction.commit(); } } finally { _transaction.dispose(); _session.dispose(); } } public void commit() { if (!_isalive) return; _iscommitted = true; } internal t get<t>(int id) { return _session.get<t>(id); } internal void saveorupdate<t>(t entity) { _session.saveorupdate(entity); } internal iqueryable<t> query<t>() { return _session.query<t>(); } }
database.sql建表语句:
create database [sqlwithmongo] go use [sqlwithmongo] go /****** 表 [dbo].[ids] ******/ set ansi_nulls on go set quoted_identifier on go create table [dbo].[ids]( [entityname] [nvarchar](100) not null, [nexthigh] [int] not null, constraint [pk_ids] primary key clustered ( [entityname] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary] go /****** 表 [dbo].[mongonode] ******/ set ansi_nulls on go set quoted_identifier on go create table [dbo].[mongonode]( [mongonodeid] [int] not null, [name] [nvarchar](100) not null, constraint [pk_mongonode] primary key clustered ( [mongonodeid] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary] go /****** 表 [dbo].[node] ******/ set ansi_nulls on go set quoted_identifier on go create table [dbo].[node]( [nodeid] [int] not null, [name] [nvarchar](100) not null, constraint [pk_networknode] primary key clustered ( [nodeid] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary] go /****** 表 [dbo].[node_node] ******/ set ansi_nulls on go set quoted_identifier on go create table [dbo].[node_node]( [nodeid1] [int] not null, [nodeid2] [int] not null, constraint [pk_networknode_networknode] primary key clustered ( [nodeid1] asc, [nodeid2] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary] go alter table [dbo].[node_node] with check add constraint [fk_networknode_networknode_networknode] foreign key([nodeid1]) references [dbo].[node] ([nodeid]) go alter table [dbo].[node_node] check constraint [fk_networknode_networknode_networknode] go alter table [dbo].[node_node] with check add constraint [fk_networknode_networknode_networknode1] foreign key([nodeid2]) references [dbo].[node] ([nodeid]) go alter table [dbo].[node_node] check constraint [fk_networknode_networknode_networknode1] go insert dbo.ids (entityname, nexthigh) values ('mongonode', 0) insert dbo.ids (entityname, nexthigh) values ('node', 0)
结果如图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读