Skip to content

Settings.MultiContextAllFieldsProcessing

Simon Hughes edited this page Aug 30, 2026 · 1 revision

Settings.MultiContextAllFields*Processing

Four callbacks that hand you the extra columns you added to the multi-context settings tables, so your own configuration data can drive generation.

Type Action<Column, Table, Dictionary<string, object>> and three siblings
Default Do nothing
Applies to Multi-context generation only (Settings.GenerateSingleDbContext = false)
Databases SQL Server, the only database the multi-context settings reader supports
In Database.tt? Yes, with commented-out examples

The four are the same idea at four levels:

Setting Signature
Settings.MultiContextAllFieldsColumnProcessing Action<Column, Table, Dictionary<string, object>>
Settings.MultiContextAllFieldsTableProcessing Action<Table, Dictionary<string, object>>
Settings.MultiContextAllFieldsStoredProcedureProcessing Action<StoredProcedure, Dictionary<string, object>>
Settings.MultiContextAllFieldsFunctionProcessing Action<StoredProcedure, Dictionary<string, object>>

What they do

Multi-context generation reads which tables, columns and procedures each DbContext should contain from a set of MultiContext.* tables in your database. The generator knows about the columns it defined - Name, IsPrimaryKey, Attributes and so on - and reads those into strongly typed properties.

It also reads every other column in those tables into a Dictionary<string, object> keyed by column name, and hands it to these callbacks. So if you add a column of your own, you can act on it:

ALTER TABLE MultiContext.[Column] ADD Sensitivity varchar(20) NULL;
ALTER TABLE MultiContext.[Table]  ADD OwningTeam  varchar(50) NULL;
Settings.MultiContextAllFieldsColumnProcessing = delegate(Column column, Table table, Dictionary<string, object> allFields)
{
    // Tag columns the security team flagged, so the attribute travels with the schema
    object sensitivity;
    if (allFields.TryGetValue("Sensitivity", out sensitivity) && sensitivity is string)
        column.Attributes.Add(string.Format("[Sensitive(\"{0}\")]", sensitivity));
};

Settings.MultiContextAllFieldsTableProcessing = delegate(Table table, Dictionary<string, object> allFields)
{
    object team;
    if (allFields.TryGetValue("OwningTeam", out team) && team is string)
        table.AdditionalComment = "Owned by " + team;
};

The Column, Table and StoredProcedure you are handed are the same objects Settings.UpdateColumn and Settings.UpdateTable receive, so anything you can do there you can do here.

Why this exists

The point of multi-context generation is that the database is the configuration: one row per column, per context, describing what each API is allowed to see. That works for the things the generator already models, and stops working the moment you need something it does not model - a data classification, an owning team, a deprecation date.

These callbacks are the escape hatch. Add a column, read it back, do what you like with it. The generator does not need to know what your column means.

When to use them

  • Attributes driven by data rather than by a rule in the .tt - anything where the list of affected columns lives with the DBAs rather than the developers.
  • Documentation, pulling a description or an owner into the generated comments.
  • Per-context renaming, where one physical column should be called different things in different contexts.

If your rule only reads properties the generator already models, use Settings.UpdateColumn instead. That one runs for single-context generation too, so it keeps working if you ever collapse back to one DbContext.

Gotchas

They only run for multi-context generation. With Settings.GenerateSingleDbContext = true - the default - there are no MultiContext.* tables in play and these never fire. Nothing warns you.

Values are object and a null database column arrives as DBNull.Value, not null. DBNull.Value is a real object, so a != null check passes and your code then formats the string "null" into an attribute. Test with is string, as above, or compare against DBNull.Value explicitly.

Keys are database column names and the lookup is case-sensitive. allFields["OwningTeam"] and allFields["owningteam"] are different lookups, and a miss throws rather than returning null - which is why the examples use TryGetValue.

Functions do not go to the stored procedure callback. Table-valued and scalar-valued functions are handed to MultiContextAllFieldsFunctionProcessing, even though both callbacks receive a StoredProcedure. Wire up both if you want to cover everything.

See also

Clone this wiki locally