当前位置: 移动技术网 > IT编程>数据库>MongoDB > SqlServer与MongoDB结合使用NHibernate

SqlServer与MongoDB结合使用NHibernate

2017年12月08日  | 移动技术网IT编程  | 我要评论

本文实例为大家分享了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) 

结果如图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网