The DBDictionary class is a container object that stores named entries of other database objects. Dictionaries provide a hierarchical structure for organizing custom data, settings, and objects in an AutoCAD drawing. The most important dictionary is the Named Objects Dictionary (NOD), accessible from the Database.
Autodesk.AutoCAD.DatabaseServices
System.Object
└─ RXObject
└─ DBObject
└─ DBDictionary
| Property | Type | Description |
|---|---|---|
Count |
int |
Gets the number of entries in the dictionary |
TreatElementsAsHard |
bool |
Gets/sets whether dictionary entries are hard-owned or soft-owned |
IsClonable |
bool |
Gets whether the dictionary can be cloned |
MergeStyle |
DictionaryMergeStyle |
Gets/sets how the dictionary is merged during WBLOCK operations |
| Method | Return Type | Description |
|---|---|---|
SetAt(string, DBObject) |
ObjectId |
Adds or replaces an entry in the dictionary |
GetAt(string) |
ObjectId |
Gets the ObjectId of an entry by key name |
Contains(string) |
bool |
Checks if a key exists in the dictionary |
Remove(string) |
void |
Removes an entry from the dictionary |
GetEnumerator() |
IEnumerator |
Gets an enumerator to iterate through entries |
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Get the Named Objects Dictionary (NOD)
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
ed.WriteMessage($"\n=== Named Objects Dictionary ===");
ed.WriteMessage($"\nTotal entries: {nod.Count}");
ed.WriteMessage($"\nTreat elements as hard: {nod.TreatElementsAsHard}");
// List all top-level entries
ed.WriteMessage("\n\nTop-level entries:");
foreach (DBDictionaryEntry entry in nod)
{
DBObject obj = tr.GetObject(entry.Value, OpenMode.ForRead);
ed.WriteMessage($"\n {entry.Key} ({obj.GetType().Name})");
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite) as DBDictionary;
string dictName = "MyCompanyData";
// Check if dictionary already exists
if (!nod.Contains(dictName))
{
// Create new dictionary
DBDictionary customDict = new DBDictionary();
// Add to NOD
ObjectId dictId = nod.SetAt(dictName, customDict);
tr.AddNewlyCreatedDBObject(customDict, true);
ed.WriteMessage($"\nCreated custom dictionary: {dictName}");
ed.WriteMessage($"\nDictionary ObjectId: {dictId}");
}
else
{
ed.WriteMessage($"\nDictionary '{dictName}' already exists");
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
// Get or create custom dictionary
DBDictionary customDict;
if (nod.Contains("MyCompanyData"))
{
customDict = tr.GetObject(nod.GetAt("MyCompanyData"), OpenMode.ForWrite) as DBDictionary;
}
else
{
nod.UpgradeOpen();
customDict = new DBDictionary();
nod.SetAt("MyCompanyData", customDict);
tr.AddNewlyCreatedDBObject(customDict, true);
}
// Create and add XRecords
string[] recordNames = { "ProjectInfo", "Settings", "Metadata" };
foreach (string recordName in recordNames)
{
if (!customDict.Contains(recordName))
{
XRecord xRec = new XRecord();
ResultBuffer rb = new ResultBuffer(
new TypedValue((int)DxfCode.Text, recordName),
new TypedValue((int)DxfCode.Text, DateTime.Now.ToString()),
new TypedValue((int)DxfCode.Int32, 1)
);
xRec.Data = rb;
customDict.SetAt(recordName, xRec);
tr.AddNewlyCreatedDBObject(xRec, true);
rb.Dispose();
ed.WriteMessage($"\nAdded entry: {recordName}");
}
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
if (nod.Contains("MyCompanyData"))
{
DBDictionary customDict = tr.GetObject(nod.GetAt("MyCompanyData"), OpenMode.ForRead) as DBDictionary;
ed.WriteMessage($"\n=== MyCompanyData Dictionary ===");
ed.WriteMessage($"\nEntries: {customDict.Count}");
// Method 1: Using foreach with DBDictionaryEntry
foreach (DBDictionaryEntry entry in customDict)
{
DBObject obj = tr.GetObject(entry.Value, OpenMode.ForRead);
ed.WriteMessage($"\n Key: {entry.Key}");
ed.WriteMessage($"\n Type: {obj.GetType().Name}");
ed.WriteMessage($"\n ObjectId: {entry.Value}");
if (obj is XRecord)
{
XRecord xRec = obj as XRecord;
ResultBuffer rb = xRec.Data;
if (rb != null)
{
ed.WriteMessage($"\n Data items: {rb.AsArray().Length}");
rb.Dispose();
}
}
}
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite) as DBDictionary;
// Create main dictionary
DBDictionary mainDict = new DBDictionary();
nod.SetAt("ProjectData", mainDict);
tr.AddNewlyCreatedDBObject(mainDict, true);
// Create nested dictionaries
string[] categories = { "Structural", "Mechanical", "Electrical" };
foreach (string category in categories)
{
DBDictionary categoryDict = new DBDictionary();
mainDict.SetAt(category, categoryDict);
tr.AddNewlyCreatedDBObject(categoryDict, true);
// Add XRecords to each category
XRecord xRec = new XRecord();
ResultBuffer rb = new ResultBuffer(
new TypedValue((int)DxfCode.Text, $"{category} Data"),
new TypedValue((int)DxfCode.Real, 100.0)
);
xRec.Data = rb;
categoryDict.SetAt("Info", xRec);
tr.AddNewlyCreatedDBObject(xRec, true);
rb.Dispose();
ed.WriteMessage($"\nCreated category: {category}");
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Access Group Dictionary
DBDictionary groupDict = tr.GetObject(db.GroupDictionaryId, OpenMode.ForRead) as DBDictionary;
ed.WriteMessage($"\n=== Groups ===");
ed.WriteMessage($"\nTotal groups: {groupDict.Count}");
foreach (DBDictionaryEntry entry in groupDict)
{
Group group = tr.GetObject(entry.Value, OpenMode.ForRead) as Group;
ed.WriteMessage($"\n {entry.Key}: {group.Count} objects");
}
// Access Layout Dictionary
DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
ed.WriteMessage($"\n\n=== Layouts ===");
ed.WriteMessage($"\nTotal layouts: {layoutDict.Count}");
foreach (DBDictionaryEntry entry in layoutDict)
{
Layout layout = tr.GetObject(entry.Value, OpenMode.ForRead) as Layout;
ed.WriteMessage($"\n {layout.LayoutName} (Model: {layout.ModelType})");
}
// Access Material Dictionary
DBDictionary materialDict = tr.GetObject(db.MaterialDictionaryId, OpenMode.ForRead) as DBDictionary;
ed.WriteMessage($"\n\n=== Materials ===");
ed.WriteMessage($"\nTotal materials: {materialDict.Count}");
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Get an entity
Entity ent = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;
// Create extension dictionary if it doesn't exist
if (ent.ExtensionDictionary == ObjectId.Null)
{
ent.CreateExtensionDictionary();
ed.WriteMessage("\nCreated extension dictionary");
}
// Access the extension dictionary
DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary;
// Add custom data
XRecord xRec = new XRecord();
ResultBuffer rb = new ResultBuffer(
new TypedValue((int)DxfCode.Text, "EntityMetadata"),
new TypedValue((int)DxfCode.Text, "Author"),
new TypedValue((int)DxfCode.Text, "John Doe"),
new TypedValue((int)DxfCode.Text, "Date"),
new TypedValue((int)DxfCode.Text, DateTime.Now.ToString("yyyy-MM-dd"))
);
xRec.Data = rb;
extDict.SetAt("Metadata", xRec);
tr.AddNewlyCreatedDBObject(xRec, true);
rb.Dispose();
ed.WriteMessage($"\nAttached metadata to {ent.GetType().Name}");
ed.WriteMessage($"\nExtension dictionary entries: {extDict.Count}");
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
if (nod.Contains("MyCompanyData"))
{
DBDictionary customDict = tr.GetObject(nod.GetAt("MyCompanyData"), OpenMode.ForWrite) as DBDictionary;
// Remove a specific entry
string entryToRemove = "Settings";
if (customDict.Contains(entryToRemove))
{
customDict.Remove(entryToRemove);
ed.WriteMessage($"\nRemoved entry: {entryToRemove}");
}
// Remove all entries
List<string> keysToRemove = new List<string>();
foreach (DBDictionaryEntry entry in customDict)
{
keysToRemove.Add(entry.Key);
}
foreach (string key in keysToRemove)
{
customDict.Remove(key);
ed.WriteMessage($"\nRemoved: {key}");
}
ed.WriteMessage($"\nRemaining entries: {customDict.Count}");
}
tr.Commit();
}using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite) as DBDictionary;
// Create dictionary with hard ownership (default)
DBDictionary hardDict = new DBDictionary();
hardDict.TreatElementsAsHard = true; // Entries are hard-owned (deleted with dictionary)
nod.SetAt("HardOwnedDict", hardDict);
tr.AddNewlyCreatedDBObject(hardDict, true);
// Create dictionary with soft ownership
DBDictionary softDict = new DBDictionary();
softDict.TreatElementsAsHard = false; // Entries are soft-owned (not deleted with dictionary)
nod.SetAt("SoftOwnedDict", softDict);
tr.AddNewlyCreatedDBObject(softDict, true);
ed.WriteMessage("\nCreated dictionaries with different ownership:");
ed.WriteMessage($"\n HardOwnedDict: TreatElementsAsHard = {hardDict.TreatElementsAsHard}");
ed.WriteMessage($"\n SoftOwnedDict: TreatElementsAsHard = {softDict.TreatElementsAsHard}");
tr.Commit();
}public void SearchDictionariesRecursive(ObjectId dictId, Transaction tr, Editor ed, int level = 0)
{
DBDictionary dict = tr.GetObject(dictId, OpenMode.ForRead) as DBDictionary;
string indent = new string(' ', level * 2);
foreach (DBDictionaryEntry entry in dict)
{
DBObject obj = tr.GetObject(entry.Value, OpenMode.ForRead);
ed.WriteMessage($"\n{indent}{entry.Key} ({obj.GetType().Name})");
if (obj is DBDictionary)
{
// Recursively search nested dictionary
SearchDictionariesRecursive(entry.Value, tr, ed, level + 1);
}
else if (obj is XRecord)
{
XRecord xRec = obj as XRecord;
ResultBuffer rb = xRec.Data;
if (rb != null)
{
ed.WriteMessage($" - {rb.AsArray().Length} items");
rb.Dispose();
}
}
}
}
// Usage:
using (Transaction tr = db.TransactionManager.StartTransaction())
{
ed.WriteMessage("\n=== Dictionary Hierarchy ===");
SearchDictionariesRecursive(db.NamedObjectsDictionaryId, tr, ed);
tr.Commit();
}The Database class provides access to several standard dictionaries:
| Property | Dictionary Purpose |
|---|---|
NamedObjectsDictionaryId |
Root dictionary for all named objects |
GroupDictionaryId |
Object groups |
LayoutDictionaryId |
Paper space layouts |
MLStyleDictionaryId |
Multiline styles |
PlotSettingsDictionaryId |
Plot configurations |
ColorDictionaryId |
Color definitions |
MaterialDictionaryId |
Material definitions |
VisualStyleDictionaryId |
Visual styles |
- Dictionary owns its entries
- When dictionary is erased, all entries are erased
- Entries cannot exist without the dictionary
- Default for most dictionaries
- Dictionary references its entries
- When dictionary is erased, entries remain
- Entries can exist independently
- Used when multiple dictionaries reference the same objects
- Check for Existence: Always use
Contains()before accessing dictionary entries - Transaction Management: Always use transactions when modifying dictionaries
- Naming Conventions: Use descriptive, unique names for dictionary entries
- Hierarchical Organization: Use nested dictionaries to organize complex data structures
- Extension Dictionaries: Use entity extension dictionaries for entity-specific data
- Ownership Awareness: Understand hard vs soft ownership implications
- Enumeration Safety: Collect keys before removing entries during enumeration
- Dispose Resources: Dispose ResultBuffers when reading XRecord data
Store application-wide settings in a custom dictionary under the NOD:
Named Objects Dictionary
└─ MyAppSettings (DBDictionary)
├─ Configuration (XRecord)
├─ Preferences (XRecord)
└─ LicenseInfo (XRecord)
Organize project data hierarchically:
Named Objects Dictionary
└─ ProjectData (DBDictionary)
├─ Structural (DBDictionary)
│ ├─ Beams (XRecord)
│ └─ Columns (XRecord)
├─ Mechanical (DBDictionary)
└─ Electrical (DBDictionary)
Attach custom data to specific entities:
Entity (Line, Circle, etc.)
└─ Extension Dictionary
├─ Metadata (XRecord)
├─ CustomProperties (XRecord)
└─ History (XRecord)