Transforms & Hooks¶
Meerkat provides built-in attributes for automatic string transformations and lifecycle methods for custom business logic before and after document persistence.
Data Transformations¶
Apply [Lowercase] or [Uppercase] attributes to model string properties to transform their values automatically before each document save.
using meerkat;
using meerkat.Attributes;
public class User : Schema<Guid>
{
[Lowercase]
public string Email { get; set; } = string.Empty;
[Uppercase]
public string CountryCode { get; set; } = string.Empty;
}
Constraints & Validation¶
- Both attributes are strictly restricted to properties of type
string. - Applying
[Lowercase]or[Uppercase]to non-string properties throws anInvalidAttributeExceptionat runtime when inspected. - Null string values are safely ignored and remain
null.
Lifecycle Hooks¶
Override the PreSave and PostSave virtual methods on any model inheriting from Schema<TId> to run custom logic during document persistence:
using meerkat;
using MongoDB.Bson;
public class Student : Schema<ObjectId>
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public override void PreSave()
{
// Executes after timestamp generation and case transformations,
// right before the document is written to MongoDB.
FirstName = FirstName?.Trim() ?? string.Empty;
LastName = LastName?.Trim() ?? string.Empty;
}
public override void PostSave()
{
// Executes immediately after the MongoDB ReplaceOne write completes.
}
}
Execution Order during Save¶
When calling Save() or SaveAsync() (and in bulk SaveAll() / SaveAllAsync()):
- Timestamps: Sets
CreatedAt(if first save) andUpdatedAt(ifTrackTimestamps = true). - Transforms: Evaluates
[Lowercase]and[Uppercase]attributes on string properties. - PreSave: Calls the model's
PreSave()method. - Database Write: Executes
ReplaceOnewith upsert enabled on MongoDB. - PostSave: Calls the model's
PostSave()method.
Write-Path Difference
Partial updates (via Update<TSchema, TId>(), UpdateOne, UpdateMany, UpdateByFilter, or atomic increment/decrement helpers) do not invoke PreSave(), PostSave(), or data transformations because documents are modified directly at the field level within MongoDB.