复制SharePoint列表项(SPListItem)到另一个列表
从理论上讲,有一个简单到难以置信的解决办法:SPListItem提供了一个CopyTo(destinationUrl)方法(可参考MSDN)。不幸的是,这个方法似乎用不了。至少对我的情况(一个带附件的自定义列表)是如此。总是告诉我找不到源列表项,没有读取权限,或者列表没有发布等等。从网上找到很多帖子,其他人也遇到同样的问题。最好的解决方案就是自己实现。
首先设计方法的参数和返回值类型:
1
|
public static SPListItem CopyItem(SPListItem sourceItem, string destinationListName) |
内容部分首先是创建目标列表项。然后把源列表项的字段复制到目标项。
1
2
3
4
5
6
7
8
9
10
|
//复制sourceItem到destinationList SPList destinationList=sourceItem.Web.Lists(destinationListName); SPListItem targetItem=destinationList.Items.Add(); foreach (SPField f in sourceItem.Fields) { if (!f.ReadOnlyField && f.InternalName!= "Attachments" ) { targentItem[f.InternalName]=sourceItem[f.InternalName]; } } |
代码中跳过了只读字段和附件。对于附件我们这样处理:
1
2
3
4
5
6
7
8
|
//复制附件 foreach ( string fileName in sourceItem.Attachments) { SPFile file=sourceItem.ParentList.ParentWeb.GetFile( sourceItem.Attachments.UrlPrefix+fileName); byte [] imageData=file.OpenBinary(); targetItem.Attachments.Add(fileName,imageData); } |
接下来只需提交目标项至数据库并返回即可。
1
2
3
|
//保存targetItem targetItem.Update(); return targetItem; |
对该方法的调用方法大致如下:
1
|
SPListItem approvedItem=CommonFunctions.CopyItem(item, "目标列表名" ); |
为了方便Copy,下面列出完整的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public static SPListItem CopyItem(SPListItem sourceItem, string destinationListName) { //复制 sourceItem 到 destinationList SPList destinationList = sourceItem.Web.Lists[destinationListName]; SPListItem targetItem = destinationList.Items.Add(); foreach (SPField f in sourceItem.Fields) { if (!f.ReadOnlyField && f.InternalName != “Attachments”) { targetItem[f.InternalName] = sourceItem[f.InternalName]; } } //复制附件 foreach ( string fileName in sourceItem.Attachments) { SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName); byte [] imageData = file.OpenBinary(); targetItem.Attachments.Add(fileName, imageData); } targetItem.Update(); return targetItem; } |
对于需要进一步对目标项进行跟踪的情况而言。默认SharePoint的SPListItem带有一个_CopySource字段,并且还有一个对应的CopySource属性。应该是与CopyTo方法配合用的。同样不幸的是都是只读的。没法为我所用。基于这个原因Muhimbi的做法是在目标列表上新建一个自己的字段——_M_CopySource,来实现类似的功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
SPList sourceList = MyWorkflow.List; SPList destinationList = MyWorkflow.Web.Lists[MyWorkflow.Parameter1 as String]; SPListItem sourceItem = MyWorkflow.Item; // 首先检查自定义的来源字段在目标列表中是否存在 if (destinationList.Fields.ContainsField( "_M_CopySource" ) == false ) { SPField newField = destinationList.Fields.CreateNewField( "Text" , "_M_CopySource" ); newField.Hidden = true ; destinationList.Fields.Add(newField); } // 检查是否存在需要更新的列表项 string camlQuery = "<Where>" + "<Eq><FieldRef Name='_M_CopySource'/><Value Type='Text'>{0}</Value></Eq>" + "</Where>" ; camlQuery = string .Format(camlQuery, sourceItem[ "FileRef" ]); SPQuery query = new SPQuery(); query.Query = camlQuery; query.RowLimit = 1; // 查询列表 SPListItemCollection items = destinationList.GetItems(query); SPListItem newItem = null ; if (items.Count == 0) newItem = destinationList.Items.Add(); else newItem = items[0]; // 复制字段 foreach (SPField field in sourceItem.Fields) { if (newItem.Fields.ContainsField(field.InternalName) == true && field.ReadOnlyField == false && field.InternalName != "Attachments" ) { newItem[field.InternalName] = sourceItem[field.InternalName]; } } // 删除目标项上已有的附件 for ( int i = newItem.Attachments.Count; i > 0; i-- ) { newItem.Attachments.Delete(newItem.Attachments[i-1]); } // 复制所有的附件 foreach ( string fileName in sourceItem.Attachments) { SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName); byte [] imageData = file.OpenBinary(); newItem.Attachments.Add(fileName, imageData); } // 在目标项上记下复制的来源,以便将来对其进行更新 newItem[ "_M_CopySource" ] = sourceItem[ "FileRef" ]; newItem.Update(); |
他是把这段代码用在自定义工作流活动中。实现列表项的单向同步更新。如果在查询中添加上我们自己的条件,就可以实现满足特定条件的更新。确实很有用。
参考资料
SharePoint Listenelement (SPListItem) in eine andere Liste kopieren
Synchronise SharePoint Lists (Calendar/Tasks) using the Workflow Power Pack
复制SharePoint列表项(SPListItem)到另一个列表的更多相关文章
- MFC CListCtrl 将一个列表的选中项添加到另一个列表
MFC CListCtrl 将一个列表的选中项添加到另一个列表, 用VC6.0实现: 简单记录一下自己的学习历程, 和大家分享,如果对你有用,我很高兴. 1.新建一个基于对话框的工程(Dialog-B ...
- Flutter 实战(一):列表项内容可自定义的列表组件
前言 本篇文的目的是熟练掌握 Flutter 组件的封装,并且使用回调函数实现主要功能. 本组件的设计灵感来源于 Element 组件库的 table 组件. 正题 定义回调函数 在此之前,必须要了解 ...
- Python3基础 把一个列表中内容给另外一个列表,形成两个独立的列表
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- 从0开始学FreeRTOS-(列表与列表项)-3
# FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像. 在`FreeRTOS`中,列表与列表项使用得非常多 ...
- 从0开始学FreeRTOS-(列表&列表项)-6
# FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像. 在FreeRTOS中,列表与列表项使用得非常多,是Free ...
- SharePoint REST API - 列表和列表项
博客地址:http://blog.csdn.net/FoxDave 本篇主要讲述如何用SharePoint REST操作列表和列表项.阅读本篇时请先了解前面讲述的REST介绍和基本操作. 废话不多 ...
- SharePoint 2010 列表项事件接收器 ItemAdded 的使用方法
列表项事件处理器是继承于Microsoft.SharePoint.SPItemEventReceiver的类,Microsoft.SharePoint.SPItemEventReceiver类提供了许 ...
- WPF中反转3D列表项
原文:WPF中反转3D列表项 WPF中反转3D列表项 周银辉记得在苹果电脑中有一个很酷的 ...
- IE问题——列表项图像
等我们实现列表时,经常会遇到一种情况:需要为列表的每一项的前面添加一个列表项图像. 我们在查阅W3C时会发现,在CSS中已经为我们提供了实现方法——“list-style-type”,我们来看看它的实 ...
随机推荐
- Spark数据传输及ShuffleClient(源码阅读五)
我们都知道Spark的每个task运行在不同的服务器节点上,map输出的结果直接存储到map任务所在服务器的存储体系中,reduce任务有可能不在同一台机器上运行,所以需要远程将多个map任务的中间结 ...
- dubbo-admin和dubbo-monitor-simple的布署
dubbo-admin 把dubbo-admin的war包解压到tomcat或者jetty的ROOT目录下,启动就可以访问了(自己配置tomcat的端口) wget http://code.aliba ...
- interview que
百度: MySQL InnoDB存储的文件结构 索引树是如何维护的? 数据库自增主键可能的问题 Redis的并发竞争问题如何解决了解Redis事务的CAS操作吗 分析线程池的实现原理和线程的调度过程 ...
- 获取JAVA[WEB]项目相关路径的几种方法
在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是WebRoot/WEB-INF/classes 当然你也可以用System.getPro ...
- JavaScript的学习2
1. a.字符串运算符 符号 功能 + 字符串连接 += 将左边的值加上右边的值然后再赋值给左边的变量 b.比较运算符 运算符 含义 说明 > 大于 M>N,当M大于N时,返回TRUE ...
- [DFNews] Cellebrite UFED Physical Analyzer 3.8
Cellebrite 两周前正式发布了UFED设备所附带的Physical Analyzer和Logical Analyzer软件,更新后版本为3.8 下载地址已更新至置顶资源下载页面. 主要更新如下 ...
- Laravel学习笔记(一)安装配置开发环境
摘要 Laravel的目标是给开发者创造一个愉快的开发过程,并且不牺牲应用的功能性.快乐的开发者才能创造最棒的代码!为了这个目的,开发者博取众框架之长处集中到Laravel中,这些框架甚至是基于Rub ...
- [python实现设计模式]-1. 单例模式
设计模式中,最简单的一个就是 “单例模式”, 那么首先,就实现一下单例模式. 那么根据个人的理解,很快就写出第一版. # -*- coding: utf-8 -*- class Singleton(o ...
- 查询oracle连接数 对应的 应用程序
select b.MACHINE, b.PROGRAM , count(*) from v$process a, v$session b where a.ADDR = b.PADDR and b ...
- SQLServer2008-镜像数据库实施手册(双机)SQL-Server2014同样适用
SQL Server2008R2-镜像数据库实施手册(双机)SQL Server2014同样适用 一.配置主备机 1. 服务器基本信息 主机名称为:HOST_A,IP地址为:192.168.1.155 ...