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]","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]GOUSE [sqlWithMongo]GO/****** 表 [dbo].[IDs] ******/SET ANSI_NulLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE 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 ONGOSET QUOTED_IDENTIFIER ONGOCREATE table [dbo].[MongoNode]( [MongoNodeID] [int] NOT NulL,[name] [nvarchar](100) NOT NulL,CONSTRAINT [PK_MongoNode] PRIMARY KEY CLUSTERED ( [MongoNodeID] ASC)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]GO/****** 表 [dbo].[Node] ******/SET ANSI_NulLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE table [dbo].[Node]( [NodeID] [int] NOT NulL,CONSTRAINT [PK_NetworkNode] PRIMARY KEY CLUSTERED ( [NodeID] ASC)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]GO/****** 表 [dbo].[Node_Node] ******/SET ANSI_NulLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE 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,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]GOALTER table [dbo].[Node_Node] WITH CHECK ADD CONSTRAINT [FK_NetworkNode_NetworkNode_NetworkNode] FOREIGN KEY([NodeID1])REFERENCES [dbo].[Node] ([NodeID])GOALTER table [dbo].[Node_Node] CHECK CONSTRAINT [FK_NetworkNode_NetworkNode_NetworkNode]GOALTER table [dbo].[Node_Node] WITH CHECK ADD CONSTRAINT [FK_NetworkNode_NetworkNode_NetworkNode1] FOREIGN KEY([NodeID2])REFERENCES [dbo].[Node] ([NodeID])GOALTER table [dbo].[Node_Node] CHECK CONSTRAINT [FK_NetworkNode_NetworkNode_NetworkNode1]GOINSERT dbo.IDs (Entityname,NextHigh)VALUES ('MongoNode',0)INSERT dbo.IDs (Entityname,NextHigh)VALUES ('Node',0)结果如图: 总结
以上是内存溢出为你收集整理的SqlServer与MongoDB结合使用NHibernate全部内容,希望文章能够帮你解决SqlServer与MongoDB结合使用NHibernate所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)