In this topic
Attachment tables
To create feature attachments, an attachment table must exist for a feature class. To access, create, or remove a feature class's attachment table, cast the class to the ITableAttachments interface. This interface exposes the following properties:
- HasAttachments - Read-only Boolean property that indicates whether an attachment table exists for a feature class.
- AttachmentManager - Read-only property instantiates and returns an attachment manager for the feature class and its attachment table. An attachment manager is used to query, add, delete, and update attachments through the IAttachmentManager interface.
ITableAttachments also defines the following methods (both have void return types and no parameters):
- AddAttachments - Creates an attachment table for the feature class. Feature classes cannot have multiple attachment tables.
- DeleteAttachments - Deletes the attachment table.
When an attachment table is created, a composite one-to-many relationship class is also created between the feature class and its attachment table. Since the relationship class is composite, developers should be aware that deleting features also deletes any attachments the features might have.
Querying attachments
There are two ways to browse attachments: by the ObjectIDs of the attachments and by the ObjectIDs of the features they are attached to. The methods used in both cases - GetAttachmentsByAttachmentIDs and GetAttachmentsByParentIDs, respectively - are very similar. Both of these methods take two parameters, an array of ObjectIDs and a Boolean, and return an enumerator of attachments.
The Boolean parameter ("Info Only") of these methods determines which properties of the returned attachments will be populated. The IAttachment interface defines the following properties:
- AttachmentID - Attachment's ObjectID.
- ContentType - Describes the type of data contained in the attachment.
- Data - Attachment's data.
- Name - Attachment's file name.
- ParentID - ObjectID of the associated feature.
- Size - Size of the attachment's data in bytes.
If the "Info Only" parameter is true, the Data property is returned as a null value. This provides applications with an efficient way of browsing attachments. However, if the client code retrieves the attachment's data, the "Info Only" parameter should be false.
The following code example shows how to browse the attachments associated with a feature that has an ObjectID of 1:
[C#] // Get the class's attachment manager.
ITableAttachments tableAttachments=(ITableAttachments)featureClass;
IAttachmentManager attachmentManager=tableAttachments.AttachmentManager;
// Create an array and add the feature's ObjectID to it.
ILongArray parentIdArray=new LongArrayClass();
parentIdArray.Add(1);
// Retrieve the attachments, writing their Attachment IDs and names to the console.
IEnumAttachment enumAttachment=attachmentManager.GetAttachmentsByParentIDs
(parentIdArray, true);
enumAttachment.Reset();
IAttachment attachment=null;
while ((attachment=enumAttachment.Next()) != null)
{
Console.WriteLine("{0}: {1}", attachment.AttachmentID, attachment.Name);
}
[VB.NET] ' Get the class's attachment manager.
Dim tableAttachments As ITableAttachments=CType(featureClass, ITableAttachments)
Dim attachmentManager As IAttachmentManager=tableAttachments.AttachmentManager
' Create an array and add the feature's ObjectID to it.
Dim parentIdArray As ILongArray=New LongArrayClass()
parentIdArray.Add(1)
' Retrieve the attachments, writing their Attachment IDs and names to the console.
Dim enumAttachment As IEnumAttachment=attachmentManager.GetAttachmentsByParentIDs(parentIdArray, True)
enumAttachment.Reset()
Dim attachment As IAttachment=enumAttachment.Next()
While Not attachment Is Nothing
Console.WriteLine("{0}: {1}", attachment.AttachmentID, attachment.Name)
attachment=enumAttachment.Next()
End While
The order in which attachments are returned by the attachment manager is not guaranteed.
To work with an attachment's data, use the IMemoryBlobStream interface. The following code example shows how to save an attachment's file to disk given a known Attachment ID:
[C#] // Create an array and add the attachment's Attachment ID to it.
ILongArray attachmentIdArray=new LongArrayClass();
attachmentIdArray.Add(attachmentID);
// Retrieve the attachment, saving its data to the current directory.
IEnumAttachment enumAttachment=attachmentManager.GetAttachmentsByAttachmentIDs
(attachmentIdArray, false);
enumAttachment.Reset();
IAttachment attachment=enumAttachment.Next();
if (attachment != null)
{
IMemoryBlobStream memoryBlobStream=attachment.Data;
memoryBlobStream.SaveToFile(attachment.Name);
}
[VB.NET] ' Create an array and add the attachment's Attachment ID to it.
Dim attachmentIdArray As ILongArray=New LongArrayClass()
attachmentIdArray.Add(attachmentID)
' Retrieve the attachment, saving its data to the current directory.
Dim enumAttachment As IEnumAttachment=attachmentManager.GetAttachmentsByAttachmentIDs(attachmentIdArray, False)
enumAttachment.Reset()
Dim attachment As IAttachment=enumAttachment.Next()
If Not attachment Is Nothing Then
Dim memoryBlobStream As IMemoryBlobStream=attachment.Data
memoryBlobStream.SaveToFile(attachment.Name)
End If
Adding attachments
Adding attachments to a feature is a three-step process, assuming the feature's ObjectID is known. See the following:
- Load a file into a memory blob stream.
- Instantiate an attachment and set its properties.
- Use the attachment manager to apply the attachment to the feature.
The following code example shows how to do this:
[C#] // Open a file as a memory blob stream.
IMemoryBlobStream memoryBlobStream=new MemoryBlobStreamClass();
memoryBlobStream.LoadFromFile("Image1.png");
// Create an attachment.
IAttachment attachment=new AttachmentClass
{
ContentType="image/png", Data=memoryBlobStream, Name="Image1.png"
};
// Assign the attachment to the feature with ObjectID (OID)=1.
attachmentManager.AddAttachment(1, attachment);
[VB.NET] ' Open a file as a memory blob stream.
Dim memoryBlobStream As IMemoryBlobStream=New MemoryBlobStreamClass()
memoryBlobStream.LoadFromFile("Image1.png")
' Create an attachment.
Dim attachment As IAttachment=New AttachmentClass With _
{ _
.ContentType="image/png", _
.Data=memoryBlobStream, _
.Name="Image1.png" _
}
' Assign the attachment to the feature with ObjectID (OID)=1.
attachmentManager.AddAttachment(1, attachment)
Deleting attachments
IAttachmentManager has the following methods that can be used to delete attachments:
- DeleteAttachment - Deletes a single attachment using its Attachment ID.
- DeleteAttachmentsForParent - Deletes all attachments for a single feature (takes the feature's ObjectID as a parameter).
As previously mentioned, due to the composite relationship class between feature classes and their attachment tables, attachments are automatically deleted if the features they are associated with are deleted.
Updating attachments
To update an attachment, use GetAttachmentsByParentIDs or GetAttachmentsByAttachmentIDs to retrieve one or more attachments, modify the attachments using the IAttachment interface, then pass each modified attachment to the IAttachmentManager.UpdateAttachment method to persist the changes to the geodatabase.
Not all properties of an attachment can be modified. For example, Attachment IDs and Parent IDs are immutable. The Size property cannot be manually changed, but it is recalculated when the attachment's data is changed.
The following code example shows how to rename an attachment:
[C#] // Rename a previously retrieved attachment and persist the change.
attachment.Name="LosAngeles.png";
attachmentManager.UpdateAttachment(attachment);
[VB.NET] ' Rename a previously retrieved attachment and persist the change.
attachment.Name="LosAngeles.png"
attachmentManager.UpdateAttachment(attachment)
To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
- ESRI.ArcGIS.Geodatabase
- ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)
Development licensing | Deployment licensing |
---|---|
ArcGIS Desktop Basic | ArcGIS Desktop Basic |
ArcGIS Desktop Standard | ArcGIS Desktop Standard |
ArcGIS Desktop Advanced | ArcGIS Desktop Advanced |
Engine Developer Kit | Engine |