diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png
new file mode 100644
index 0000000000..2e415e8cd3
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png
new file mode 100644
index 0000000000..f2e1bd42a5
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png
new file mode 100644
index 0000000000..c22f33befe
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png
new file mode 100644
index 0000000000..ff5422297f
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-blazor-webapp.png
new file mode 100644
index 0000000000..d1ee92c5e6
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png
new file mode 100644
index 0000000000..07dc46fc76
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png
new file mode 100644
index 0000000000..0d460c984d
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png
new file mode 100644
index 0000000000..eea6b6b5a0
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/images/catalog-module-vs-code-blazor-webapp.png b/docs/en/tutorials/modular-crm/images/catalog-module-vs-code-blazor-webapp.png
new file mode 100644
index 0000000000..83a196713a
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/catalog-module-vs-code-blazor-webapp.png differ
diff --git a/docs/en/tutorials/modular-crm/index.md b/docs/en/tutorials/modular-crm/index.md
index 856fe7957f..afa8eaede7 100644
--- a/docs/en/tutorials/modular-crm/index.md
+++ b/docs/en/tutorials/modular-crm/index.md
@@ -7,6 +7,13 @@
# Modular Monolith Application Development Tutorial
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
diff --git a/docs/en/tutorials/modular-crm/part-01.md b/docs/en/tutorials/modular-crm/part-01.md
index 862f5ecc6b..2ccd86bc28 100644
--- a/docs/en/tutorials/modular-crm/part-01.md
+++ b/docs/en/tutorials/modular-crm/part-01.md
@@ -7,6 +7,13 @@
# Creating the Initial Solution
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -28,7 +35,7 @@ In this first part of this tutorial, we will create a new ABP solution with modu
Follow the *[Get Started](../../get-started/single-layer-web-application.md)* guide to create a single layer web application with the following configuration:
* **Solution name**: `ModularCrm`
-* **UI Framework**: ASP.NET Core MVC / Razor Pages
+* **UI Framework**: {{if UI == "MVC"}}ASP.NET Core MVC / Razor Pages{{else if UI == "BlazorWebApp"}}Blazor WebApp{{end}}
* **Database Provider**: Entity Framework Core
You can select the other options based on your preference but at the **Modularity** step, check the _Setup as a modular solution_ option and add a new **Standard Module** named `ModularCrm.Catalog`:
@@ -62,12 +69,16 @@ Initially, you see a `ModularCrm` solution with two solution folders:
If you expand it, you can see the .NET projects (ABP Studio Packages) of the `ModularCrm.Catalog` module:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
- `ModularCrm.Catalog`: The main module project that contains your [entities](../../framework/architecture/domain-driven-design/entities.md), [application service](../../framework/architecture/domain-driven-design/application-services.md) implementations and other business objects
- `ModularCrm.Catalog.Contracts`: Basically contains [application service](../../framework/architecture/domain-driven-design/application-services.md) interfaces and [DTOs](../../framework/architecture/domain-driven-design/data-transfer-objects.md). These interfaces then can be used by client modules for integration purposes or by the user interface to perform use cases related to that module
- `ModularCrm.Catalog.Tests`: Unit and integration tests (if you selected the _Include Tests_ option) for that module
-- `ModularCrm.Catalog.UI`: Contains user interface pages and components for the module
+- {{if UI == "MVC"}}`ModularCrm.Catalog.UI`: Contains user interface pages and components for the module{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`: Contains Blazor WebApp user interface pages and components for the module{{end}}
## Summary
diff --git a/docs/en/tutorials/modular-crm/part-02.md b/docs/en/tutorials/modular-crm/part-02.md
index 9e715b6c30..06aae6eac3 100644
--- a/docs/en/tutorials/modular-crm/part-02.md
+++ b/docs/en/tutorials/modular-crm/part-02.md
@@ -7,6 +7,13 @@
# Setting Up the Catalog Module
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -25,7 +32,7 @@ In this part, you will install the `ModularCrm.Catalog` module to the main appli
## Installing the Catalog Module to the Main Application
-A module does not contain an executable application inside. The `ModularCrm.Catalog.UI` project is just a class library project, not an executable web application. A module should be installed in an executable application to run it.
+A module does not contain an executable application inside. The {{if UI == "MVC"}}`ModularCrm.Catalog.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`{{end}} project is just a class library project, not an executable web application. A module should be installed in an executable application to run it.
> **Ensure that the web application is not running in [Solution Runner](../../studio/running-applications.md) or in your IDE. Installing a module to a running application will produce errors.**
@@ -41,9 +48,13 @@ Select the `ModularCrm.Catalog` module and check the *Install this module* optio
When you click the *OK* button, ABP Studio opens the *Install Module* dialog:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
-Select the `ModularCrm.Catalog` and `ModularCrm.Catalog.UI` packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
+Select the `ModularCrm.Catalog` and {{if UI == "MVC"}}`ModularCrm.Catalog.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`{{end}} packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
## Building the Main Application
diff --git a/docs/en/tutorials/modular-crm/part-03.md b/docs/en/tutorials/modular-crm/part-03.md
index 36b418c7fb..a8f1f2a0c7 100644
--- a/docs/en/tutorials/modular-crm/part-03.md
+++ b/docs/en/tutorials/modular-crm/part-03.md
@@ -7,6 +7,13 @@
# Building the Catalog Module
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -35,7 +42,11 @@ Open the `ModularCrm.Catalog` module in your favorite IDE. You can right-click t
The `ModularCrm.Catalog` .NET solution should look like the following figure:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
Add a new `Product` class under the `ModularCrm.Catalog` project:
@@ -406,6 +417,8 @@ As a first step, you can stop the application on ABP Studio's Solution Runner if
### Creating the Products Page
+{{if UI == "MVC"}}
+
Open the `ModularCrm.Catalog` .NET solution in your IDE, and find the `Pages/Catalog/Index.cshtml` file under the `ModularCrm.Catalog.UI` project:

@@ -461,7 +474,50 @@ Here, you simply use the `IProductAppService` to get a list of all products and
````
-Right-click the `ModularCrm` application on ABP Studio's solution runner and select the *Start* command:
+{{else if UI == "BlazorWebApp"}}
+
+Open the `ModularCrm.Catalog` .NET solution in your IDE, and find the `Pages/Catalog/Index.razor` file under the `ModularCrm.Catalog.Blazor` project.
+> Blazor WebApp placeholder screenshot file: `images/vscode-catalog-index-razor-blazor-webapp.png`
+
+Replace the `Index.razor` file with the following content:
+
+````razor
+@page "/catalog"
+@using System.Collections.Generic
+@using System.Threading.Tasks
+@using ModularCrm.Catalog
+@inject IProductAppService ProductAppService
+
+
Products
+
+
+
+
+ @foreach (var product in Products)
+ {
+
+ @product.Name (stock: @product.StockCount)
+
+ }
+
+
+
+
+@code {
+ private List Products { get; set; } = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ Products = await ProductAppService.GetListAsync();
+ }
+}
+````
+
+Here, you inject `IProductAppService`, get all products in `OnInitializedAsync`, and then render the result in a simple list.
+
+{{end}}
+
+Right-click the `ModularCrm` application on ABP Studio's Solution Runner and select the *Start* command:

diff --git a/docs/en/tutorials/modular-crm/part-04.md b/docs/en/tutorials/modular-crm/part-04.md
index bc2fa9fa4c..554c34acd1 100644
--- a/docs/en/tutorials/modular-crm/part-04.md
+++ b/docs/en/tutorials/modular-crm/part-04.md
@@ -7,6 +7,13 @@
# Creating the Initial Ordering Module
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -39,9 +46,13 @@ That command opens a dialog to define the properties of the new module:
Set `ModularCrm.Ordering` as the *Module name*, leave the *Output folder* as is and click the *Next* button.
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
-You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the *MVC* option and click *Next*.
+You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the {{if UI == "MVC"}}*MVC*{{else if UI == "BlazorWebApp"}}*Blazor WebApp*{{end}} option and click *Next*.

@@ -53,7 +64,11 @@ You can include or not include unit tests for the new module here. We are unchec
Here is the final solution structure after adding the `ModularCrm.Ordering` module:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
## Installing into the Main Application
@@ -71,9 +86,13 @@ That command opens the *Import Module* dialog:
Select the `ModularCrm.Ordering` module and check the *Install this module* option as shown in the preceding figure. When you click the OK button, a new dialog is shown to select the packages to install:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
-Select the `ModularCrm.Ordering` and `ModularCrm.Ordering.UI` packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
+Select the `ModularCrm.Ordering` and {{if UI == "MVC"}}`ModularCrm.Ordering.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Ordering.Blazor`{{end}} packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
## Summary
diff --git a/docs/en/tutorials/modular-crm/part-05.md b/docs/en/tutorials/modular-crm/part-05.md
index fa3c2769a4..e85a3b9597 100644
--- a/docs/en/tutorials/modular-crm/part-05.md
+++ b/docs/en/tutorials/modular-crm/part-05.md
@@ -7,6 +7,13 @@
# Building the Ordering Module
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -379,12 +386,14 @@ If you check the database, you should see the entities created in the *Orders* t
## Creating the User Interface
-In this section, you will create a very simple user interface to demonstrate how to build UI in the catalog module and make it work in the main application.
+In this section, you will create a very simple user interface to demonstrate how to build UI in the ordering module and make it work in the main application.
As a first step, you can stop the application on ABP Studio's Solution Runner if it is currently running.
### Creating the Orders Page
+{{if UI == "MVC"}}
+
Replace the `Index.cshtml.cs` content in the `Pages/Ordering` folder of the `ModularCrm.Ordering.UI` project with the following code block:
````csharp
@@ -481,6 +490,91 @@ public class OrderingMenuContributor : IMenuContributor
> You can check the [menu documentation](../../framework/ui/mvc-razor-pages/navigation-menu.md) to learn more about manipulating menu items.
+{{else if UI == "BlazorWebApp"}}
+
+Replace the `Index.razor` content in the `Pages/Ordering` folder of the `ModularCrm.Ordering.Blazor` project with the following code block:
+> Blazor WebApp placeholder screenshot file: `images/vscode-ordering-index-razor-blazor-webapp.png`
+
+````razor
+@page "/ordering"
+@using System.Collections.Generic
+@using System.Threading.Tasks
+@using ModularCrm.Ordering
+@inject IOrderAppService OrderAppService
+
+Orders
+
+
+
+
+ @foreach (var order in Orders)
+ {
+
+ Customer: @order.CustomerName
+ Product: @order.ProductId
+ State: @order.State
+
+ }
+
+
+
+
+@code {
+ private List Orders { get; set; } = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ Orders = await OrderAppService.GetListAsync();
+ }
+}
+````
+
+This page shows a list of orders on the UI. You haven't created a UI to create new orders, and we will not do it to keep this tutorial simple. If you want to learn how to create advanced UIs with ABP, please follow the [Book Store tutorial](../book-store/index.md).
+
+### Editing the Menu Item
+
+ABP provides a modular navigation [menu system](../../framework/ui/blazor/navigation-menu.md) where each module can contribute to the main menu dynamically.
+
+Edit the `OrderingMenuContributor` class in the `ModularCrm.Ordering.Blazor` project:
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.UI.Navigation;
+
+namespace ModularCrm.Ordering.Blazor.Menus;
+
+public class OrderingMenuContributor : IMenuContributor
+{
+ public async Task ConfigureMenuAsync(MenuConfigurationContext context)
+ {
+ if (context.Menu.Name == StandardMenus.Main)
+ {
+ await ConfigureMainMenuAsync(context);
+ }
+ }
+
+ private Task ConfigureMainMenuAsync(MenuConfigurationContext context)
+ {
+ context.Menu.AddItem(
+ new ApplicationMenuItem(
+ OrderingMenus.Prefix, // Unique menu id
+ "Orders", // Menu display text
+ "/ordering", // URL
+ "fa-solid fa-basket-shopping" // Icon CSS class
+ )
+ );
+
+ return Task.CompletedTask;
+ }
+}
+````
+
+`OrderingMenuContributor` implements the `IMenuContributor` interface, which forces us to implement the `ConfigureMenuAsync` method. In that method, you can manipulate the menu items (add new menu items, remove existing menu items or change the properties of existing menu items). The `ConfigureMenuAsync` method is executed whenever the menu is rendered on the UI, so you can dynamically decide how to manipulate the menu items.
+
+> You can check the [menu documentation](../../framework/ui/blazor/navigation-menu.md) to learn more about manipulating menu items.
+
+{{end}}
+
### Building the Application
Now, you will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm` application, and select the *Build* -> *Graph Build* command:
diff --git a/docs/en/tutorials/modular-crm/part-06.md b/docs/en/tutorials/modular-crm/part-06.md
index c4ad6a5e6f..31551f7c58 100644
--- a/docs/en/tutorials/modular-crm/part-06.md
+++ b/docs/en/tutorials/modular-crm/part-06.md
@@ -7,6 +7,13 @@
# Integrating the Modules: Implementing Integration Services
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -138,7 +145,11 @@ Open the ABP Studio UI and stop the application if it is already running. Then o
In the opening dialog, select the *This solution* tab, find and check the `ModularCrm.Catalog.Contracts` package and click the OK button:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
ABP Studio adds the package reference and arranges the [module](../../framework/architecture/modularity/basics.md) dependency.
@@ -249,7 +260,9 @@ Let's see what we've changed:
* In the last line, we are converting the product list to a dictionary, where the key is `Guid Id` and the value is `string Name`. That way, we can easily find a product's name with its ID.
* Finally, we are mapping the orders to `OrderDto` objects and setting the product name by looking up the product ID in the dictionary.
-Open the `Index.cshtml` file, and change the `@order.ProductId` part by `@Order.ProductName` to write the product name instead of the product ID. The final `Index.cshtml` content should be the following:
+{{if UI == "MVC"}}
+
+Open the `Index.cshtml` file, and change the `@order.ProductId` part to `@order.ProductName` to write the product name instead of the product ID. The final `Index.cshtml` content should be the following:
````html
@page
@@ -273,6 +286,46 @@ Open the `Index.cshtml` file, and change the `@order.ProductId` part by `@Order.
````
+{{else if UI == "BlazorWebApp"}}
+
+Open the `Index.razor` file, and change the `@order.ProductId` part to `@order.ProductName` to write the product name instead of the product ID. The final `Index.razor` content should be the following:
+
+````razor
+@page "/ordering"
+@using System.Collections.Generic
+@using System.Threading.Tasks
+@using ModularCrm.Ordering
+@inject IOrderAppService OrderAppService
+
+Orders
+
+
+
+
+ @foreach (var order in Orders)
+ {
+
+ Customer: @order.CustomerName
+ Product: @order.ProductName
+ State: @order.State
+
+ }
+
+
+
+
+@code {
+ private List Orders { get; set; } = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ Orders = await OrderAppService.GetListAsync();
+ }
+}
+````
+
+{{end}}
+
That's all. Now, you can graph build the main application and run it in ABP Studio to see the result:

diff --git a/docs/en/tutorials/modular-crm/part-07.md b/docs/en/tutorials/modular-crm/part-07.md
index 454c62d780..8d93fa9794 100644
--- a/docs/en/tutorials/modular-crm/part-07.md
+++ b/docs/en/tutorials/modular-crm/part-07.md
@@ -7,6 +7,13 @@
# Integrating the Modules: Communication via Messages (Events)
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
@@ -158,13 +165,21 @@ In the opening dialog, find and select the `ModularCrm.Ordering` module, check t
Once you click the OK button, the Ordering module is imported to the Catalog module, and an installation dialog is open:
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
Here, select the `ModularCrm.Ordering.Contracts` package on the left side (because we want to add that package reference) and `ModularCrm.Catalog` package on the middle area (because we want to add the package reference to that project). Also, select the `ModularCrm.Ordering` package on the right side, and unselect all packages on the middle area (we don't need the implementation or any other packages). Then, click the OK button to finish the installation operation.
You can check the ABP Studio's *Solution Explorer* panel to see the module import and the project reference (dependency).
+{{if UI == "MVC"}}

+{{else if UI == "BlazorWebApp"}}
+
+{{end}}
### Handling the `OrderPlacedEto` Event
diff --git a/docs/en/tutorials/modular-crm/part-08.md b/docs/en/tutorials/modular-crm/part-08.md
index d4a78a6b53..cfcb4ee592 100644
--- a/docs/en/tutorials/modular-crm/part-08.md
+++ b/docs/en/tutorials/modular-crm/part-08.md
@@ -7,6 +7,13 @@
# Integrating the Modules: Joining the Products and Orders Data
+````json
+//[doc-params]
+{
+ "UI": ["MVC","BlazorWebApp"]
+}
+````
+
````json
//[doc-nav]
{
diff --git a/modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.Designer.cs b/modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.Designer.cs
new file mode 100644
index 0000000000..b95e114e8c
--- /dev/null
+++ b/modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.Designer.cs
@@ -0,0 +1,1538 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+using VoloDocs.EntityFrameworkCore;
+
+#nullable disable
+
+namespace Migrations
+{
+ [DbContext(typeof(VoloDocsDbContext))]
+ [Migration("20260227074745_ABP10_2")]
+ partial class ABP10_2
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
+ .HasAnnotation("ProductVersion", "10.0.2")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("ContainerId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Content")
+ .HasMaxLength(2147483647)
+ .HasColumnType("varbinary(max)");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ContainerId");
+
+ b.HasIndex("TenantId", "ContainerId", "Name");
+
+ b.ToTable("AbpBlobs", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Name");
+
+ b.ToTable("AbpBlobContainers", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("Description")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Regex")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("RegexDescription")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Required")
+ .HasColumnType("bit");
+
+ b.Property("ValueType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpClaimTypes", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
+ .IsUnique()
+ .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL");
+
+ b.ToTable("AbpLinkUsers", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("EntityVersion")
+ .HasColumnType("int");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDefault")
+ .HasColumnType("bit")
+ .HasColumnName("IsDefault");
+
+ b.Property("IsPublic")
+ .HasColumnType("bit")
+ .HasColumnName("IsPublic");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit")
+ .HasColumnName("IsStatic");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName");
+
+ b.ToTable("AbpRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AbpRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Action")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Identity")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Action");
+
+ b.HasIndex("TenantId", "ApplicationName");
+
+ b.HasIndex("TenantId", "Identity");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSecurityLogs", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AccessFailedCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(0)
+ .HasColumnName("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Email");
+
+ b.Property("EmailConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("EmailConfirmed");
+
+ b.Property("EntityVersion")
+ .HasColumnType("int");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsActive")
+ .HasColumnType("bit")
+ .HasColumnName("IsActive");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("IsExternal")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsExternal");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("LastPasswordChangeTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("LastSignInTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Leaved")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("Leaved");
+
+ b.Property("LockoutEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("LockoutEnabled");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Name");
+
+ b.Property("NormalizedEmail")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedEmail");
+
+ b.Property("NormalizedUserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedUserName");
+
+ b.Property("PasswordHash")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("PasswordHash");
+
+ b.Property("PhoneNumber")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)")
+ .HasColumnName("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("SecurityStamp");
+
+ b.Property("ShouldChangePasswordOnNextLogin")
+ .HasColumnType("bit");
+
+ b.Property("Surname")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Surname");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TwoFactorEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email");
+
+ b.HasIndex("NormalizedEmail");
+
+ b.HasIndex("NormalizedUserName");
+
+ b.HasIndex("UserName");
+
+ b.ToTable("AbpUsers", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AbpUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("SourceUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("StartTime")
+ .HasColumnType("datetime2");
+
+ b.Property("TargetUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpUserDelegations", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderDisplayName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(196)
+ .HasColumnType("nvarchar(196)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "LoginProvider");
+
+ b.HasIndex("LoginProvider", "ProviderKey");
+
+ b.ToTable("AbpUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "UserId");
+
+ b.HasIndex("UserId", "OrganizationUnitId");
+
+ b.ToTable("AbpUserOrganizationUnits", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasskey", b =>
+ {
+ b.Property("CredentialId")
+ .HasMaxLength(1024)
+ .HasColumnType("varbinary(1024)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("CredentialId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AbpUserPasskeys", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasswordHistory", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Password")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "Password");
+
+ b.ToTable("AbpUserPasswordHistories", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId", "UserId");
+
+ b.ToTable("AbpUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AbpUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(95)
+ .HasColumnType("nvarchar(95)")
+ .HasColumnName("Code");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("DisplayName");
+
+ b.Property("EntityVersion")
+ .HasColumnType("int");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ParentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Code");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("AbpOrganizationUnits", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "RoleId");
+
+ b.HasIndex("RoleId", "OrganizationUnitId");
+
+ b.ToTable("AbpOrganizationUnitRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("GroupName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("IsEnabled")
+ .HasColumnType("bit");
+
+ b.Property("ManagementPermissionName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("MultiTenancySide")
+ .HasColumnType("tinyint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ParentName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Providers")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ResourceName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("StateCheckers")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GroupName");
+
+ b.HasIndex("ResourceName", "Name")
+ .IsUnique()
+ .HasFilter("[ResourceName] IS NOT NULL");
+
+ b.ToTable("AbpPermissions", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey")
+ .IsUnique()
+ .HasFilter("[TenantId] IS NOT NULL");
+
+ b.ToTable("AbpPermissionGrants", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("AbpPermissionGroups", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.PermissionManagement.ResourcePermissionGrant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ResourceKey")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ResourceName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Name", "ResourceName", "ResourceKey", "ProviderName", "ProviderKey")
+ .IsUnique()
+ .HasFilter("[TenantId] IS NOT NULL");
+
+ b.ToTable("AbpResourcePermissionGrants", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderName")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name", "ProviderName", "ProviderKey")
+ .IsUnique()
+ .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL");
+
+ b.ToTable("AbpSettings", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DefaultValue")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("Description")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsEncrypted")
+ .HasColumnType("bit");
+
+ b.Property("IsInherited")
+ .HasColumnType("bit");
+
+ b.Property("IsVisibleToClients")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Providers")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("AbpSettingDefinitions", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Docs.Documents.Document", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Content")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("EditLink")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("FileName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Format")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LanguageCode")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastCachedTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastSignificantUpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastUpdatedTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LocalDirectory")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("ProjectId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RawRootUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("RootUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("Version")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.HasKey("Id");
+
+ b.ToTable("DocsDocuments", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
+ {
+ b.Property("DocumentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Username")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AvatarUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CommitCount")
+ .HasColumnType("int");
+
+ b.Property("UserProfileUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("DocumentId", "Username");
+
+ b.ToTable("DocsDocumentContributors", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Docs.Projects.Project", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("DefaultDocumentName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("DocumentStoreType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Format")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LatestVersionBranchName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("MainWebsiteUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("MinimumVersion")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("NavigationDocumentName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ParametersDocumentName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ShortName")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.HasKey("Id");
+
+ b.ToTable("DocsProjects", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Docs.Projects.ProjectPdfFile", b =>
+ {
+ b.Property("ProjectId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("FileName")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("LanguageCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("Version")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("ProjectId", "FileName");
+
+ b.ToTable("DocsProjectPdfFiles", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b =>
+ {
+ b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null)
+ .WithMany()
+ .HasForeignKey("ContainerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Volo.Abp.Identity.IdentityRole", null)
+ .WithMany("Claims")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Volo.Abp.Identity.IdentityUser", null)
+ .WithMany("Claims")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Volo.Abp.Identity.IdentityUser", null)
+ .WithMany("Logins")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
+ {
+ b.HasOne("Volo.Abp.Identity.OrganizationUnit", null)
+ .WithMany()
+ .HasForeignKey("OrganizationUnitId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Volo.Abp.Identity.IdentityUser", null)
+ .WithMany("OrganizationUnits")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasskey", b =>
+ {
+ b.HasOne("Volo.Abp.Identity.IdentityUser", null)
+ .WithMany("Passkeys")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("Volo.Abp.Identity.IdentityPasskeyData", "Data", b1 =>
+ {
+ b1.Property("IdentityUserPasskeyCredentialId");
+
+ b1.Property("AttestationObject");
+
+ b1.Property("ClientDataJson");
+
+ b1.Property("CreatedAt");
+
+ b1.Property("IsBackedUp");
+
+ b1.Property("IsBackupEligible");
+
+ b1.Property