侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

SqlServer与MongoDB结合使用NHibernate

数据库  /  管理员 发布于 5年前   204

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

结果如图:

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


  • 上一条:
    MongoDB运行状态监控、性能分析工具mongostat详解
    下一条:
    MongoDB的安装方法图文教程
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客