-
Notifications
You must be signed in to change notification settings - Fork 226
Settings.MultiContextAllFieldsProcessing
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>> |
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.
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.
-
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.
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.
- Generating Multiple Database Contexts in a Single Go - the setup these belong to
- Settings.UpdateColumn - the single-context equivalent
- Settings.MultiContextAttributeDelimiter
- Settings Reference
- Settings A-Z - every setting, with a page each
- Common Settings Types Explained
- Settings Callbacks
- Settings runtime values and helpers
- Filtering
- Full Control Over the Generated Code
- Enum Generation from Table Data
- Owned Entities
- JSON column support
- Global Query Filters
- Extended Property Names Feature
- Partial Properties
- File-Scoped Namespaces
- Data Annotations
- Spatial Types
- HierarchyId
- RowVersion and TimeStamp columns
- Lazy Loading
- Stored proc result sets
- Custom File-Based Templates
- Extra entities via partial classes
- INotifyPropertyChanged
- Syntax colour for T4