-
Notifications
You must be signed in to change notification settings - Fork 224
Generating Multiple Database Contexts in a Single Go
This enterprise feature reads filter and settings data from database tables and generates many DbContext classes in one pass. The database schema is read once; hundreds of contexts can be produced with separate namespaces and access rules.
Use case: High-security microservice architectures where each API should only have access to the tables and columns it strictly needs.
Run the setup SQL script to create the settings tables in your database:
Settings.DatabaseType = DatabaseType.SqlServer;
Settings.TemplateType = TemplateType.EfCore10; // Or Ef6, EfCore8, EfCore9
Settings.GeneratorType = GeneratorType.EfCore; // Or Ef6
Settings.UseMappingTables = false;
Settings.FileManagerType = FileManagerType.EfCore;
Settings.ConnectionString = "Data Source=(local);Initial Catalog=EfrpgTest;Integrated Security=True;Encrypt=false;TrustServerCertificate=true";
Settings.ConnectionStringName = "MyDbContext";
Settings.GenerateSeparateFiles = false;
Settings.Namespace = DefaultNamespace;
Settings.AddUnitTestingDbContext = false;
// Enable multi-context mode
Settings.GenerateSingleDbContext = false;
// Connection string to the database containing multi-context settings
// Leave empty to read from the same database as ConnectionString
Settings.MultiContextSettingsConnectionString = "Data Source=(local);Initial Catalog=EfrpgTest_Settings;Integrated Security=True;Encrypt=false;TrustServerCertificate=true";Tip: Set
Settings.GenerateSeparateFiles = falsewhen multiple contexts share identical table names to prevent generated class files from overwriting each other.
You can add custom data annotations to columns via the settings database. Use a tilde ~ as the delimiter between multiple attributes:
UPDATE MultiContext.[Column]
SET Attributes = '[ExampleForTesting("abc")]~[CustomRequired]'
WHERE Name = 'Dollar';Use file-based templates for full control over generated code:
Settings.TemplateType = TemplateType.FileBasedCore10;
Settings.TemplateFolder = @"C:\path_to_templates";
// Or relative:
Settings.TemplateFolder = Path.Combine(Settings.Root, "Templates");Override the template folder per individual context:
UPDATE MultiContext.Context
SET TemplatePath = 'C:\path\to\context_specific_templates'
WHERE [Name] = 'context_name';You can add extra columns to the MultiContext.[Column], MultiContext.[Table], and MultiContext.[StoredProcedure] tables for custom processing:
ALTER TABLE MultiContext.[Column] ADD Notes VARCHAR(500) NULL;
ALTER TABLE MultiContext.[Column] ADD Priority INT NULL;Then process them in Database.tt:
Settings.MultiContextAllFieldsColumnProcessing = delegate (Column column, Table table, Dictionary<string, object> allFields)
{
if (allFields.ContainsKey("Priority"))
{
var priority = (int) allFields["Priority"];
column.ExtendedProperty += $" Priority={priority}";
}
};Similarly for tables and stored procedures:
Settings.MultiContextAllFieldsTableProcessing = delegate (Table table, Dictionary<string, object> allFields)
{
if (allFields.ContainsKey("Notes"))
table.AdditionalComment = allFields["Notes"].ToString();
};
Settings.MultiContextAllFieldsStoredProcedureProcessing = delegate (StoredProcedure sp, Dictionary<string, object> allFields)
{
if (allFields.ContainsKey("CustomRename"))
sp.NameHumanCase = allFields["CustomRename"].ToString();
};The delimiter used to split multiple attribute values in the settings database:
Settings.MultiContextAttributeDelimiter = '~'; // DefaultFor advanced scenarios, you can provide a custom plugin to read multi-context settings:
Settings.MultiContextSettingsPlugin = "c:\\Path\\YourPlugin.dll,Full.Name.Of.Class.Including.Namespace";