C# 如何通过实现Orchard.Data.ISessionLocator来编写自定义Orchard会话定位器?
我需要迁移在Orchard 1.9.0安装中运行的Orchard模块中的一些数据。这里的问题是数据存储在另一台服务器上的外部数据库中,而不是存储在Orchard数据库中。因此,当调用迁移类方法时,Orchard内部使用C# 如何通过实现Orchard.Data.ISessionLocator来编写自定义Orchard会话定位器?,c#,asp.net-mvc,migration,orchardcms,C#,Asp.net Mvc,Migration,Orchardcms,我需要迁移在Orchard 1.9.0安装中运行的Orchard模块中的一些数据。这里的问题是数据存储在另一台服务器上的外部数据库中,而不是存储在Orchard数据库中。因此,当调用迁移类方法时,Orchard内部使用Orchard.Data.ISessionLocator接口检索DB连接。遗憾的是,覆盖这个行为是不可能的,但是我有一个想法,通过创建一个自定义的会话定位器来连接会话定位器 自定义会话定位器如下所示,并基于现有类Orchard.Data.SessionLocator: public
Orchard.Data.ISessionLocator
接口检索DB连接。遗憾的是,覆盖这个行为是不可能的,但是我有一个想法,通过创建一个自定义的会话定位器来连接会话定位器
自定义会话定位器如下所示,并基于现有类Orchard.Data.SessionLocator:
public class CustomSessionLocator : Orchard.Data.ISessionLocator, Orchard.Data.ITransactionManager, System.IDisposable
{
// public
public CustomSessionLocator(Orchard.Data.ISessionFactoryHolder aSessionFactoryHolder)
{
Logger = Orchard.Logging.NullLogger.Instance;
IsolationLevel = System.Data.IsolationLevel.ReadCommitted;
mSessionFactoryHolder = aSessionFactoryHolder;
mSessions = new System.Collections.Generic.Dictionary<SessionScope, NHibernate.ISession>();
if (mForeignDBConnection == null)
{
string lConnectionString = "data source=myServer;initial catalog=myDB;persist security info=True;user id=xxx;password=xxx;MultipleActiveResultSets=True;";
mForeignDBConnection = new System.Data.SqlClient.SqlConnection(lConnectionString);
}
}
public NHibernate.ISession For(System.Type aEntityType)
{
Logger.Debug("Acquiring session for {0}", aEntityType);
Demand();
return mSessions[CurrentSessionScope];
}
public void Demand()
{
EnsureSession(IsolationLevel);
}
public void RequireNew()
{
RequireNew(IsolationLevel);
}
public void RequireNew(System.Data.IsolationLevel aLevel)
{
DisposeSession();
EnsureSession(aLevel);
}
public void Cancel()
{
NHibernate.ISession lSession;
if (mSessions.TryGetValue(CurrentSessionScope, out lSession) && lSession != null && !lSession.Transaction.WasRolledBack && lSession.Transaction.IsActive)
{
Logger.Debug("Rolling back transaction");
lSession.Transaction.Rollback();
}
}
public void Dispose()
{
DisposeSession();
}
public enum SessionScope
{
OrchardDefault,
ForeignDB
}
public Orchard.Logging.ILogger Logger { get; set; }
public System.Data.IsolationLevel IsolationLevel { get; set; }
public SessionScope CurrentSessionScope { private get; set; }
// private
private void DisposeSession()
{
NHibernate.ISession lSession;
if (mSessions.TryGetValue(CurrentSessionScope, out lSession) && lSession != null)
{
try
{
if (!lSession.Transaction.WasRolledBack && lSession.Transaction.IsActive)
{
Logger.Debug("Committing transaction");
lSession.Transaction.Commit();
}
}
finally
{
Logger.Debug("Disposing session");
var lConnection = lSession.Connection;
lSession.Close();
lSession.Dispose();
lSession = null;
mSessions[CurrentSessionScope] = null;
}
}
}
private void EnsureSession(System.Data.IsolationLevel aLevel)
{
NHibernate.ISession lSession;
if (mSessions.TryGetValue(CurrentSessionScope, out lSession) && lSession != null)
return;
var lSessionFactory = mSessionFactoryHolder.GetSessionFactory();
Logger.Debug("Opening NHibernate session");
if (CurrentSessionScope == SessionScope.ForeignDB)
{
lSession = lSessionFactory.OpenSession(mForeignDBConnection);
// open connection otherwise the following lSession.BeginTransaction() fails with exception
if (mForeignDBConnection.State == System.Data.ConnectionState.Closed)
mForeignDBConnection.Open();
}
else
lSession = lSessionFactory.OpenSession();
mSessions[CurrentSessionScope] = lSession;
lSession.BeginTransaction(aLevel);
}
private readonly Orchard.Data.ISessionFactoryHolder mSessionFactoryHolder;
private System.Collections.Generic.Dictionary<SessionScope, NHibernate.ISession> mSessions;
private static System.Data.SqlClient.SqlConnection mForeignDBConnection;
}
公共类CustomSessionLocator:Orchard.Data.ISessionLocator、Orchard.Data.ITransactionManager、System.IDisposable
{
//公开的
公共CustomSessionLocator(Orchard.Data.ISessionFactoryHolder aSessionFactoryHolder)
{
Logger=Orchard.Logging.NullLogger.Instance;
IsolationLevel=System.Data.IsolationLevel.ReadCommitted;
msSessionFactoryHolder=一个SessionFactoryHolder;
mSessions=new System.Collections.Generic.Dictionary();
if(mForeignDBConnection==null)
{
string lConnectionString=“数据源=myServer;初始目录=myDB;持久安全信息=True;用户id=xxx;密码=xxx;MultipleActiveResultSets=True;”;
mForeignDBConnection=new System.Data.SqlClient.SqlConnection(lConnectionString);
}
}
用于(System.Type aEntityType)的公用NHibernate.IseSession
{
Debug(“获取{0}的会话”,aEntityType);
需求();
返回mSessions[CurrentSessionScope];
}
公共需求
{
确保发送(隔离级别);
}
公众假期(续)
{
要求更新(隔离级别);
}
公共数据更新(System.Data.IsolationLevel aLevel)
{
处置();
保证切除术(aLevel);
}
公开作废取消()
{
NHibernate.ISession-lSession;
if(mSessions.TryGetValue(CurrentSessionScope,out lSession)&&lSession!=null&&&!lSession.Transaction.wasrollledback&&lSession.Transaction.IsActive)
{
调试(“回滚事务”);
lSession.Transaction.Rollback();
}
}
公共空间处置()
{
处置();
}
公共枚举会话范围
{
果园违约,
外国的
}
public Orchard.Logging.ILogger记录器{get;set;}
public System.Data.IsolationLevel IsolationLevel{get;set;}
公共会话范围CurrentSessionScope{private get;set;}
//私人的
私人无效处置()
{
NHibernate.ISession-lSession;
if(mSessions.TryGetValue(CurrentSessionScope,out lSession)&&lSession!=null)
{
尝试
{
如果(!lSession.Transaction.wasrollledback&&lSession.Transaction.IsActive)
{
调试(“提交事务”);
lSession.Transaction.Commit();
}
}
最后
{
调试(“处理会话”);
var lConnection=lSession.Connection;
lSession.Close();
lSession.Dispose();
lSession=null;
mSessions[CurrentSessionScope]=null;
}
}
}
私密网络传输(System.Data.IsolationLevel aLevel)
{
NHibernate.ISession-lSession;
if(mSessions.TryGetValue(CurrentSessionScope,out lSession)&&lSession!=null)
返回;
var lSessionFactory=mSessionFactoryHolder.GetSessionFactory();
调试(“打开NHibernate会话”);
if(CurrentSessionScope==SessionScope.ForeignDB)
{
lSession=lSessionFactory.OpenSession(mForeignDBConnection);
//打开连接,否则以下lSession.BeginTransaction()将失败,出现异常
if(mForeignDBConnection.State==System.Data.ConnectionState.Closed)
mForeignDBConnection.Open();
}
其他的
lSession=lSessionFactory.OpenSession();
mSessions[CurrentSessionScope]=lSession;
l会议开始(阿莱维尔);
}
私有只读Orchard.Data.ISessionFactoryHolder mSessionFactoryHolder;
private System.Collections.Generic.Dictionary mSessions;
私有静态System.Data.SqlClient.SqlConnection mForeignDBConnection;
}
然后我有一个迁移数据解释器,它看起来像这样:
public class ForeignDataMigrationInterpreter : Orchard.Data.Migration.Interpreters.DefaultDataMigrationInterpreter
{
public ForeignDataMigrationInterpreter(
Orchard.Environment.Configuration.ShellSettings aShellSettings,
Orchard.Data.ISessionLocator aSessionLocator,
System.Collections.Generic.IEnumerable<Orchard.Data.Migration.Interpreters.ICommandInterpreter> aCommandInterpreters,
Orchard.Data.ISessionFactoryHolder aSessionFactoryHolder,
Orchard.Reports.Services.IReportsCoordinator aReportsCoordinator)
: base(aShellSettings, aSessionLocator, aCommandInterpreters, aSessionFactoryHolder, aReportsCoordinator)
{
mSessionLocator = aSessionLocator as CustomSessionLocator;
}
public override void Visit(Orchard.Data.Migration.Schema.CreateTableCommand aCommand)
{
#if LIVE
if (IsForeignDBCommand(aCommand.Name, ""))
mSessionLocator.CurrentSessionScope = CustomSessionLocator.SessionScope.ForeignDB;
else
mSessionLocator.CurrentSessionScope = CustomSessionLocator.SessionScope.OrchardDefault;
#endif
base.Visit(aCommand);
}
...
private bool IsForeignDBCommand(...)
{
return ...;
}
private CustomSessionLocator mSessionLocator;
}
公共类ForeignDataMigrationInterpreter:Orchard.Data.Migration.Translators.DefaultDataMigrationInterpreter
{
公共ForeignDataMigrationInterpreter(
Orchard.Environment.Configuration.ShellSettings aShellSettings,
Orchard.Data.ISessionLocator aSessionLocator,
System.Collections.Generic.IEnumerable AcommandInterpreter,
Orchard.Data.ISessionFactoryHolder aSessionFactoryHolder,
Orchard.Reports.Services.IReportsCoordinator aReportsCoordinator)
:base(aShellSettings、aSessionLocator、acommandisterpreter、aSessionFactoryHolder、aReportsCoordinator)
{
mSessionLocator=aSessionLocator作为CustomSessionLocator;
}
公共覆盖无效访问(Orchard.Data.Migration.Schema.CreateTableCommand ACOMAND)
{
#如果活着
if(IsForeignDBCommand(aCommand.Name,“”)
mSessionLocator.CurrentSessionScope=CustomSessionLocator.SessionScope.ForeignDB;
其他的
mSessionLocator.CurrentSessionScope=CustomSessionLocator.SessionScope.OrchardDefault;
#恩迪夫
基地参观(A命令);
}
...
私有bool IsForeignDBCommand(…)
{
返回。。。;
}
私有CustomSessionLocator mSessionLocator;
}
如您所见,使用外来数据的基本过程如下
Cur