About assigning domains to fields
Use domains to constrain the permissible values that can be associated with a particular field in an object or feature class. ArcMap uses domains to constrain the values that can be added into a field, as well as during the validation process in the geodatabase.
Domains are associated with a field object and are stored at the workspace level. This allows the same domain to be applied to multiple fields across objects or feature classes (from this point forward, only feature classes will be discussed, but both apply) if the field types match.
When assigning a domain to a field in a feature class, determine if the feature class has subtypes or not. See the following:
- If the feature class does not have subtypes, assign the domain directly to the field.
- If the feature class does have subtypes, assign the domain to the field through a specific subtype.
The same workflow is required to assign the domain independent of its domain type (range or coded value).
In both cases—classes with and without subtypes defined—acquire an exclusive schema lock for the class before assigning a domain to a field. The following examples include this procedure, using the ISchemaLock interface.
Assigning domains to fields in an object or feature class without defined subtypes
If an object or feature class has no subtypes defined, domains can be assigned to a field through the IClassSchemaEdit interface.
The example to assign a domain to a field has the following three arguments:
- Name of the field to which the domain is assigned
- Feature class that contains the field
- Name of the domain that exists in the workspace
The following code example verifies that a feature class was supplied and that the domain and field both exist. It also verifies that the domain and field have the same field type. If this is true, the domain is assigned with a call to AlterDomain supplying the field name and the domain to be assigned.
The following code example assigns a domain to a field in a feature class without defined subtypes:
If a field has domains assigned at both the feature class and subtype level, the subtypes domain will be used; however, you should avoid this situation if possible.
// For example: domainName = "Material".
// fieldName = "CP_MATERIAL".
public void AssignDomainToField(IFeatureClass featureClass, String domainName,
String fieldName)
{
// Cast the feature class to IDataset to get a reference to the workspace.
IDataset dataset = (IDataset)featureClass;
// Get the workspace and cast it to the IWorkspaceDomains interface and get the requested domain.
IWorkspace workspace = dataset.Workspace;
IWorkspaceDomains workspaceDomains = (IWorkspaceDomains)workspace;
IDomain domain = workspaceDomains.get_DomainByName(domainName);
// Get the field to assign the domain to.
IFields fields = featureClass.Fields;
int fieldIndex = featureClass.FindField(fieldName);
IField field = fields.get_Field(fieldIndex);
// Check that the field and domain have the same field type.
if (field.Type == domain.FieldType)
{
// Cast the feature class to the ISchemaLock and IClassSchemaEdit interfaces.
ISchemaLock schemaLock = (ISchemaLock)featureClass;
IClassSchemaEdit classSchemaEdit = (IClassSchemaEdit)featureClass;
// Attempt to get an exclusive schema lock.
try
{
// Lock the class and alter the domain.
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
classSchemaEdit.AlterDomain(fieldName, domain);
Console.WriteLine("The domain was successfully assigned.");
}
catch (Exception exc)
{
// Handle the exception in a way appropriate for the application.
Console.WriteLine(exc.Message);
}
finally
{
// Set the schema lock to be a shared lock.
schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}
}
else
{
Console.WriteLine("The field and the domain have different field types: " +
"Field = {0}, Domain = {1}", field.Type, domain.FieldType);
}
}
[VB.NET]
' For example: domainName = "Material".
' fieldName = "CP_MATERIAL".
Public Sub AssignDomainToField(ByVal featureClass As IFeatureClass, ByVal domainName As String, ByVal fieldName As String)
' Cast the feature class to IDataset to get a reference to the workspace.
Dim dataset As IDataset = CType(featureClass, IDataset)
' Get the workspace and cast it to the IWorkspaceDomains interface and get the requested domain.
Dim workspace As IWorkspace = dataset.Workspace
Dim workspaceDomains As IWorkspaceDomains = CType(workspace, IWorkspaceDomains)
Dim domain As IDomain = workspaceDomains.DomainByName(domainName)
' Get the field to assign the domain to.
Dim fields As IFields = featureClass.Fields
Dim fieldIndex As Integer = featureClass.FindField(fieldName)
Dim field As IField = fields.Field(fieldIndex)
' Check that the field and domain have the same field type.
If field.Type = domain.FieldType Then
' Cast the feature class to the ISchemaLock and IClassSchemaEdit interfaces.
Dim schemaLock As ISchemaLock = CType(featureClass, ISchemaLock)
Dim classSchemaEdit As IClassSchemaEdit = CType(featureClass, IClassSchemaEdit)
' Try to get an exclusive schema lock.
Try
' Lock the class and alter the domain.
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock)
classSchemaEdit.AlterDomain(fieldName, domain)
Console.WriteLine("The domain was successfully assigned.")
Catch exc As Exception
' Handle the exception in a way appropriate for the application.
Console.WriteLine(exc.Message)
Finally
' Set the schema lock to be a shared lock.
schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock)
End Try
Else
Console.WriteLine("The field and the domain have different field types: " & "Field = {0}, Domain = {1}", field.Type, domain.FieldType)
End If
End Sub
Assigning domains to fields in an object or feature class with defined subtypes
The second case discussed is if the feature class does have defined subtypes. In this case, the domain is assigned to the field through the ISubtypes interface.
For this example, some background information about the field and feature class is needed. Assume that a polyline feature class is being used to model pipes. The feature class has a field named TYPECODE that is used to define the subtypes. Currently, the following three subtypes are defined:
- Subtype code of 1 for distribution mains
- Subtype code of 2 for transmission mains
- Subtype code of 3 for other mains
The geodatabase in which the feature class is stored has domains for the diameters of two of the pipe types. The coded value domains are named DistDiam and TransDiam. The field that will have the domain applied to it is named SIZE_ONE.
The following code example accepts a feature class and casts it to the ISubtypes interface. Both domains are retrieved from the workspace by name and assigned to the SIZE_ONE field through the subtype code they are to be associated with. It is not necessary to assign domains (or default values) to a field for every subtype.
[C#]
public void AssignDomainToFieldWithSubtypes(IFeatureClass featureClass)
{
// Cast the feature class to IDataset to get a reference to the workspace.
IDataset dataset = (IDataset)featureClass;
// Get the workspace and cast it to the IWorkspaceDomains interface and get the requested domain.
IWorkspace workspace = dataset.Workspace;
IWorkspaceDomains workspaceDomains = (IWorkspaceDomains)workspace;
// Get the domains from the workspace.
IDomain distributionDiamDomain = workspaceDomains.get_DomainByName("DistDiam");
IDomain transmissionDiamDomain = workspaceDomains.get_DomainByName("TransDiam");
// Cast for ISubtypes.
ISubtypes subtypes = (ISubtypes)featureClass;
// Assign the domain to the SIZE_ONE field on the distribution main subtype.
subtypes.set_Domain(1, "SIZE_ONE", distributionDiamDomain);
// Assign the domain to the SIZE_ONE field on the transmission main subtype.
subtypes.set_Domain(2, "SIZE_ONE", transmissionDiamDomain);
}
[VB.NET]
Public Sub AssignDomainToFieldWithSubtypes(ByVal featureClass As IFeatureClass)
' Cast the feature class to IDataset to get a reference to the workspace.
Dim dataset As IDataset = CType(featureClass, IDataset)
' Get the workspace and cast it to the IWorkspaceDomains interface and get the requested domain.
Dim workspace As IWorkspace = dataset.Workspace
Dim workspaceDomains As IWorkspaceDomains = CType(workspace, IWorkspaceDomains)
' Get the domains from the workspace.
Dim distributionDiamDomain As IDomain = workspaceDomains.DomainByName("DistDiam")
Dim transmissionDiamDomain As IDomain = workspaceDomains.DomainByName("TransDiam")
' Cast for ISubtypes.
Dim subtypes As ISubtypes = CType(featureClass, ISubtypes)
' Assign the domain to the SIZE_ONE field on the distribution main subtype.
subtypes.Domain(1, "SIZE_ONE") = distributionDiamDomain
' Assign the domain to the SIZE_ONE field on the transmission main subtype.
subtypes.Domain(2, "SIZE_ONE") = transmissionDiamDomain
End Sub
See Also:
Creating and modifying domainsCreating subtypes
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):
Development licensing | Deployment licensing |
---|---|
ArcGIS for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
Engine Developer Kit | Engine: Geodatabase Update |