Extend Database Model¶
This tutorial provides specific steps to extend the model and persistence layer of an existing module. In this guide, we will use the Virto Commerce Orders Module as an example.
We recommend following a 3-tier architecture (Core, Data, and Web) for both custom modules and the Virto Commerce platform.
Changes in ".Core" Project¶
- Add a reference to the ".Core" NuGet package containing the base models, for example,
VirtoCommerce.OrdersModule.Core
. - Define a new model class by extending the base model in the Models folder, for example:
CustomerOrder2 : CustomerOrder
. - Add additional properties required for the new model.
Changes in ".Data" Project¶
- Add a reference to ".Data" NuGet package containing the base models, for example,
VirtoCommerce.OrdersModule.Data
. - Define a new model class by extending the base model in the Models folder, for example:
CustomerOrder2Entity : CustomerOrderEntity
. - Add additional properties required for the new model.
- Override the
ToModel
,FromModel
, andPatch
methods. -
Modify the Repositories folder:
- Define a new DbContext class by extending the parent DbContext. Add 1 public constructor and override
OnModelCreating
. Refer to the example for more details. - Create
DesignTimeDbContextFactory
for DbContext, defined in the previous step. - Optionally extend the parent repository interface by adding the
IQueryable<T>
property and additional methods as needed. -
Extend the parent repository by implementing the interface defined in the previous step. If new interface wasn't defined, override the base methods as needed. Add the
IQueryable<the new type>
, for example:
- Define a new DbContext class by extending the parent DbContext. Add 1 public constructor and override
-
Generate code-first DB migration:
- Set your ".Data" project as a startup project in Solution Explorer.
- Open the NuGet Package Manager Console.
- Select your ".Data" as the default project in the console.
-
Run the command to add a new migration. Replace
YourNewMigrationName
with the desired migration name:
-
Examine the generated code and remove the commands that do not reflect your model changes or configurations defined in your DbContext.OnModelCreating(). These changes have already been applied by migrations in the base module. Make sure that the Up() method defines:
-
New tables and indices:
-
New column(s) when modifying the existing:
-
A
Discriminator
column if new columns were defined in the previous step AND it didn't exist in the original table:migrationBuilder.AddColumn<string>(name: "Discriminator", table: "CustomerOrder", nullable: false, maxLength: 128, defaultValue: "CustomerOrder2Entity");
Note
You need to add SQL script for adding the field to
20000000000000_Update<Module>V2.cs
for backward compatibility with v.2.:If the
Discriminator
already exists and you want to migrate from v.2, add SQL script to update the field to20000000000000_Update<Module>V2.cs
for backward compatibility with v.2.: -
Any custom SQL scripts if data update is required.
-
-
The Down() method should do the opposite of what Up() does. That way you can quickly apply and unapply your changes quickly by
Update-Database
command in console.
Changes in ".Web" project¶
-
Modify the module.manifest file. Ensure that a dependency on the appropriate module is added to the dependencies section:
-
Modify the Module.cs regarding the model extension:
-
In the Initialize() method:
-
Register the new DbContext in DI:
-
Register the new Repository_ implementation in DI:
-
-
In the PostInitialize() method:
- Register type override(s) to AbstractTypeFactory.
- Register new type(s) to AbstractTypeFactory as usual.
-
Add code to ensure that the migrations from new DbContext are applied:
-
-
Test your changes in the Solution REST API documentation (Swagger) and in the database.