API Reference
Containers API
Container creation, configuration, operations, and management
#Container API
Containers organize documents into logical groups within a database. Container methods live on DocumentDatabase (PhoenixmlDb.Storage) and return IContainer (PhoenixmlDb.Core).
#Creating Containers
#Basic Creation
IContainer container = await db.CreateContainerAsync("products");
Creating a container whose name is already taken throws DocumentExistsException.
#With Options
Options are set through a configuration delegate that receives a fresh ContainerOptions:
var container = await db.CreateContainerAsync("orders", opts =>
{
opts.PreserveWhitespace = false;
opts.DefaultNamespaces["o"] = "http://example.com/orders";
opts.DefaultMetadataNamespace = "http://example.com/meta";
opts.Indexes.AddPathIndex("/o:order/o:id");
});
#Open or Create
// Creates if it doesn't exist, opens if it does
var container = await db.OpenOrCreateContainerAsync("products");
When the container already exists, the configure delegate is not applied; the container keeps the options it was created with.
#ContainerOptions
|
Property |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
|
Stored with the container; not enforced on write today (every stored document must be well-formed XML or valid JSON regardless) |
|
|
|
|
Keep whitespace-only text nodes |
|
|
|
Empty |
Prefix → namespace URI bindings available to every query on the container |
|
|
|
|
Namespace for unqualified metadata names; |
|
|
|
Structural index only |
Index declarations — see Index API |
DefaultNamespaces is validated when the container is created: a binding the XQuery compiler would refuse (rebinding a predeclared prefix such as fn or xs, xmlns, an empty URI, or a prefix that is not an NCName) throws ArgumentException from CreateContainerAsync.
#ValidationMode
public enum ValidationMode
{
None,
Schema,
WellFormed
}
#Getting Containers
// Returns null if the container does not exist
IContainer? container = await db.OpenContainerAsync("products");
if (container is not null)
{
// Use container
}
#Listing Containers
await foreach (ContainerInfo info in db.ListContainersAsync())
{
Console.WriteLine($"{info.Name}: {info.DocumentCount} documents");
}
#Container Information
ContainerInfo (PhoenixmlDb.Core) is returned by ListContainersAsync:
|
Property |
Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An open IContainer exposes Id, Name and Options.
#Deleting Containers
// Returns false if no container has that name
bool deleted = await db.DeleteContainerAsync("temp-data");
Warning: Deleting a container removes it from the database's catalogue; its documents are no longer reachable through any API. This operation cannot be undone.
#Statistics
Database-wide statistics are available from DocumentDatabase.Statistics (DatabaseStatistics, PhoenixmlDb.Core):
var stats = db.Statistics;
Console.WriteLine($"Containers: {stats.ContainerCount}");
Console.WriteLine($"Documents: {stats.TotalDocumentCount}");
Console.WriteLine($"Nodes: {stats.TotalNodeCount}");
Console.WriteLine($"Database size: {stats.DatabaseSizeBytes}");
Console.WriteLine($"Used size: {stats.UsedSizeBytes}");
There is no per-container statistics API beyond ContainerInfo.DocumentCount.
#In Transactions
Write transactions address a container by its ContainerId:
var products = await db.OpenOrCreateContainerAsync("products");
await using (var txn = await db.BeginWriteAsync())
{
await txn.PutDocumentAsync(products.Id, "p1.xml", xml1);
await txn.PutDocumentAsync(products.Id, "p2.xml", xml2);
// Commit, or dispose without committing to discard
await txn.CommitAsync();
}
#Error Handling
try
{
await db.CreateContainerAsync("existing");
}
catch (DocumentExistsException ex)
{
Console.WriteLine(ex.Message); // "Container 'existing' already exists."
}
try
{
// With indexing enabled; without it, RebuildIndexesAsync throws InvalidOperationException
await db.RebuildIndexesAsync("nonexistent");
}
catch (ContainerNotFoundException ex)
{
Console.WriteLine(ex.Message);
}
OpenContainerAsync and DeleteContainerAsync report a missing container through their return values (null / false) rather than an exception.
#Best Practices
-
Meaningful names - Use descriptive container names
-
Group related documents - Keep related data together
-
Consider query patterns - A query runs against one container; documents queried together should be in the same container
-
Use transactions - For multi-document operations
-
Declare indexes at creation - A container's index set is fixed when it is created
#Next Steps
|
Documentation |
API Reference |
Advanced Topics |
|---|---|---|
|
Document API Document operations |
Index API Container indexes |
Transaction API Transactional access |