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())

{

......

}

  

  

posted on 2014-04-14 15:28  buyone  阅读(337)  评论(0编辑  收藏  举报