orchard data access for multi-tenancy
搞了2天,orchard多租户之间数据互通,比如租户A的数据导入到租户B(这里说的数据,他们的类型都是content type)
首先使用_orchardHost.CreateStandaloneEnvironment(shellSettings) 创建一个租户B的shell实例, 然后resolve一个对象
以下4个思路
1. 获得A的Part或者PartRecord,在租户B中保存这个对象
点评:这种方式遇到很多错误,深入跟踪之后,对象中存在一对多,多对多的复杂关系的时候不可行
错误一:NHibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
错误二:System.Data.SqlServerCe.SqlCeLockTimeoutException: SQL Server Compact 等待锁超时。对于设备的默认的锁时间为 2000 毫秒,而对于台式机则为 5000 毫秒。可以在使用 ssce: default lock timeout 属性的连接字符串中增加默认的锁超时时间。 [ Session id = 2,Thread id = 5104,Process id = 2016,Table name = Orchard_Framework_ContentItemRecord,Conflict type = x lock (x blocks),Resource = PAG (idx): 1060 ]
2. 利用Orchard.ImportExport模块,在A的UI上导出,然后在租户B导入
点评:可行,但是纯手动方式,忽视之,除非程序员都死光了
3. Web API
点评:个人觉得跟方法1是类似的,最后还会遇到保存时候的问题
4. 查看Content的clone方法,在IContentManager新增自己的 Clone(XElement element) 方法
点评:就是他了。在A中获得contentItem的XElement,然后Clone(XElement element) 。
部分代码如下:
//data ready
var contentItem = _contentManager.GetLatest(part.Id);
var element = _orchardServices.ContentManager.Export(contentItem);
......
//get B _shellSettings
......
//data go
using (var env = _orchardHost.CreateStandaloneEnvironment(TenatSettings))
{
var orchardServices = env.Resolve<IOrchardServices>();
orchardServices.ContentManager.Clone(element);
}
//or method 2 推荐
var shellContext = _orchardHost.GetShellContext(tenatSettingsDefault);
using (var wc = shellContext.LifetimeScope.Resolve<IWorkContextAccessor>().CreateWorkContextScope())
{
......
}
浙公网安备 33010602011771号