您现在的位置是:网站首页> 编程资料编程资料

SqlServer与MongoDB结合使用NHibernate_MongoDB_

2023-05-27 409人已围观

简介 SqlServer与MongoDB结合使用NHibernate_MongoDB_

本文实例为大家分享了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 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 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 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 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 _collection; public IList 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 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("links", collectionSettings); } private class NodeLinks { public int Id { get; private set; } public List Links { get; private set; } public NodeLinks(int nodeId, IEnumerable links) { Id = nodeId; Links = new List(); Links.AddRange(links); } } } 
 public class NodeRepository { private readonly UnitOfWork _unitOfWork; public NodeRepository(UnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public Node GetById(int id) { return _unitOfWork.Get(id); } public IList GetAll() { return _unitOfWork.Query() .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(id); } public void Save(MongoNode mongoNode) { _unitOfWork.SaveOrUpdate(mongoNode); } public IList GetAll() { return _unitOfWork.Query() .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 LinksInternal { get; set; } public virtual IReadOnlyList Links { get { return LinksInternal.ToList(); } } protected Node() { LinksInternal = new HashSet(); } public Node(string name) : this() { Name = name; } public virtual void AddLink(Node node) { LinksInternal.Add(node); node.LinksInternal.Add(this); } } 
 public class NodeMap : ClassMap //FluentNHibernate.Mapping.ClasslikeMapBase { public NodeMap() { Id(x => x.Id, "NodeId").GeneratedBy.HiLo("[dbo].[Ids]", "NextHigh", "10", "EntityName = 'Node'"); Map(x => x.Name).Not.Nullable(); HasManyToMany(Reveal.Member("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 LinksInternal { get; set; } public virtual IReadOnlyList Links { get { return LinksInternal.ToList(); } } protected MongoNode() { LinksInternal = new HashSet(); } 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 //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 linksFromMongo = repository.GetLinks(networkNode.Id); HashSet links = (HashSet)networkNode .GetType() .GetProperty("LinksInternal", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(networkNode); links.UnionWith(linksFromMongo); } } 
 internal class Interceptor : EmptyInterceptor //NHibernate中的类 { public override void PostF
                
                

-六神源码网