遵守 SharePoint 列表的存储库模式
Adhering to a Repository Pattern for a SharePoint list
我正在使用 SharePoint 列表的存储库模式(而不是直接访问数据库中的实际 table)在列表项集合上创建一个 class。我见过的存储库模式设计不断地为每个单独的存储库创建一个新的上下文,但我想对可能存在的每个并发存储库(每个列表一个)使用相同的 ClientContext 对象。假设我不希望有人必须自己创建一个新的 ClientContext 实例,该实例将作为构造函数传递到 SPRepository class,那么我还有哪些其他选择可以将其保存在静态内存中?
参考文献:
https://msdn.microsoft.com/en-us/library/ff649690.aspx
https://hendrikbulens.wordpress.com/2014/12/14/repository-pattern-sharepoint/(这个为每个列表使用单独的存储库,而我想制作一个更通用的在构造函数中接受列表名称的存储库)
这是一个比看起来更复杂的主题,因为有很多事情需要考虑。我见过的大多数解决方案(包括您的链接)都试图以性能和资源消耗为代价使代码通用。没有万能的解决方案。
单一职责
您应该将 ClientContext
注入您的存储库,因为 CSOM 有许多不同的身份验证方案(NTLM、FBA、ADFS、具有用户身份的高信任应用、具有应用身份的高信任应用,仅举几例).存储库不应该知道创建上下文的身份验证方法和方式。
资源
在多个存储库之间共享 ClientContext
的一个实例在您想要避免创建不必要的对象的简单场景中可能是个好主意。它实现了 IDisposable
,我们应该假设这是有原因的。
调用次数 ExecuteQuery()
如果您对多个存储库使用一个 ClientContext
实例,您可以安排多个操作并通过对 SharePoint 的一个请求执行所有操作。
var result1 = repository1.ScheduleLoad();
var result2 = repository2.ScheduleLoad();
context.ExecuteQuery();
请记住,CSOM 是远程的 API。调用次数和检索的数据量将对性能产生重大影响。
从其他对象或线程调用 ExecuteQuery()
考虑一下:
var web = StaticClass.Context.Web;
var list = web.GetList('Lists/example');
var item = list.GetItemById(1);
item["Title"] = "Test";
var result = repository.GetItemsAndExecute();
//or some other thread calls StaticClass.Context.ExecuteQuery();
item.Update();
StaticClass.Context.ExecuteQuery();
结果会怎样? Title
字段的值将保持为空。原因如下:
- 第一次调用通过id获取item并设置字段值,但没有调用
Update()
.
- 第二次调用再次通过 id 获取项目并调用
Update()
,但它没有设置字段值。
我正在使用 SharePoint 列表的存储库模式(而不是直接访问数据库中的实际 table)在列表项集合上创建一个 class。我见过的存储库模式设计不断地为每个单独的存储库创建一个新的上下文,但我想对可能存在的每个并发存储库(每个列表一个)使用相同的 ClientContext 对象。假设我不希望有人必须自己创建一个新的 ClientContext 实例,该实例将作为构造函数传递到 SPRepository class,那么我还有哪些其他选择可以将其保存在静态内存中?
参考文献:
https://msdn.microsoft.com/en-us/library/ff649690.aspx https://hendrikbulens.wordpress.com/2014/12/14/repository-pattern-sharepoint/(这个为每个列表使用单独的存储库,而我想制作一个更通用的在构造函数中接受列表名称的存储库)
这是一个比看起来更复杂的主题,因为有很多事情需要考虑。我见过的大多数解决方案(包括您的链接)都试图以性能和资源消耗为代价使代码通用。没有万能的解决方案。
单一职责
您应该将 ClientContext
注入您的存储库,因为 CSOM 有许多不同的身份验证方案(NTLM、FBA、ADFS、具有用户身份的高信任应用、具有应用身份的高信任应用,仅举几例).存储库不应该知道创建上下文的身份验证方法和方式。
资源
在多个存储库之间共享 ClientContext
的一个实例在您想要避免创建不必要的对象的简单场景中可能是个好主意。它实现了 IDisposable
,我们应该假设这是有原因的。
调用次数 ExecuteQuery()
如果您对多个存储库使用一个 ClientContext
实例,您可以安排多个操作并通过对 SharePoint 的一个请求执行所有操作。
var result1 = repository1.ScheduleLoad();
var result2 = repository2.ScheduleLoad();
context.ExecuteQuery();
请记住,CSOM 是远程的 API。调用次数和检索的数据量将对性能产生重大影响。
从其他对象或线程调用 ExecuteQuery()
考虑一下:
var web = StaticClass.Context.Web;
var list = web.GetList('Lists/example');
var item = list.GetItemById(1);
item["Title"] = "Test";
var result = repository.GetItemsAndExecute();
//or some other thread calls StaticClass.Context.ExecuteQuery();
item.Update();
StaticClass.Context.ExecuteQuery();
结果会怎样? Title
字段的值将保持为空。原因如下:
- 第一次调用通过id获取item并设置字段值,但没有调用
Update()
. - 第二次调用再次通过 id 获取项目并调用
Update()
,但它没有设置字段值。