By Barbara Han
Issue
I know that I can use the PromoteFile method to make a primary link between an Item and a File but I haven't found a method that put a weak link (like secondary link). Can you help me?
Solution
The ReassignComponentsToDifferentItems function can make several files to link to an existing item after the files are prompted.
The following C# sample code demonstrates how to do that:
public void AssignFileToItem(ItemService itemSvc, Item selectedItem, File file1, File file2) { ItemsAndFiles promoteResult = null; Item[] updatedItems = null;
long itemId1 = -1; long itemId2 = -1; try { // firstly promote files to items // this example assumes that only 1 item will result from the promote
promoteResult = itemSvc.PromoteFiles(new long[] { file1.Id, file2.Id });
// Obtain the new items for files
foreach (ItemFileAssoc assoc in promoteResult.FileAssocArray) { if (assoc.CldFileId == file1.Id) { itemId1 = assoc.ParItemId; } if (assoc.CldFileId == file2.Id) { itemId2 = assoc.ParItemId; } } if (itemId1 < 0 || itemId2 < 0) { MessageBox.Show("Promote error"); } else { //next reassign an existing item to the files
updatedItems = itemSvc.ReassignComponentsToDifferentItems( new long[] { itemId1, itemId2 }, new long[] { selectedItem.Id, selectedItem.Id });
// commit the changes itemSvc.UpdateAndCommitItems(updatedItems); } } catch { if (updatedItems != null && updatedItems.Length > 0) { long[] itemIds = new long[updatedItems.Length]; for (int i = 0; i < updatedItems.Length; i++) { itemIds[i] = updatedItems[i].Id; } itemSvc.UndoEditItems(itemIds); } } finally { if (promoteResult != null) { // clear out the unused items
itemSvc.DeleteUnusedItemNumbers(new long[] { promoteResult. ItemRevArray[0].MasterId, promoteResult.ItemRevArray[0].MasterId });
itemSvc.UndoEditItems(new long[] { itemId1, itemId2 }); } } }
private void button1_Click(object sender, EventArgs e) { PropDef[] propDefs = m_serviceManager.PropertyService. GetPropertyDefinitionsByEntityClassId("FILE"); PropDef fileNamePropDef = null;
foreach (PropDef propDef in propDefs) { if (propDef.SysName == "ClientFileName") { fileNamePropDef = propDef; break; } }
// Searches specified files in the Vault. // If there are too many hits for a single search, the function loops // till all results are returned.
string bookmark = String.Empty; SrchStatus searchStatus = null; List<File> files = new List<File>();
SrchCond currentCond = new SrchCond(); currentCond.PropTyp = PropertySearchType.SingleProperty; currentCond.SrchOper = 3; //is exactly currentCond.SrchRule = SearchRuleType.May; currentCond.PropDefId = fileNamePropDef.Id; currentCond.SrchTxt = "Part5.ipt";
while (searchStatus == null || files.Count < searchStatus.TotalHits) { File[] results = m_serviceManager.DocumentService. FindFilesBySearchConditions( new SrchCond[]{currentCond}, null, null, true, true, ref bookmark, out searchStatus);
if (results != null) files.AddRange(results); } File file1 = files.ToArray()[0]; files.Clear();
searchStatus = null; bookmark = String.Empty; currentCond.SrchTxt = "Part6.ipt"; while (searchStatus == null || files.Count < searchStatus.TotalHits) { File[] results = m_serviceManager.DocumentService. FindFilesBySearchConditions( new SrchCond[] { currentCond }, null, null, true, true, ref bookmark, out searchStatus);
if (results != null) files.AddRange(results); } File file2 = files.ToArray()[0];
AssignFileToItem(m_serviceManager.ItemService, m_selectedItem, file1, file2); } |
The order of the files which are passed to PromoteFiles function decides which file is primary link. The first file is the primary link and the second file is the secondary link.