diff --git a/docs/en/Community-Articles/onur-article/Post.md b/docs/en/Community-Articles/onur-article/Post.md index 898724c2ac..5270649d4d 100644 --- a/docs/en/Community-Articles/onur-article/Post.md +++ b/docs/en/Community-Articles/onur-article/Post.md @@ -53,7 +53,7 @@ public static void ConfigureExtraProperties() }); } ``` -> This method is called inside the YourProjectNameDomainSharedModule at the beginning of the application. OneTimeRunner is a utility class that guarantees to execute this code only one time per application, since multiple calls are unnecessary. +> This method is called inside the IdentityRelationshipDomainSharedModule at the beginning of the application. OneTimeRunner is a utility class that guarantees to execute this code only one time per application, since multiple calls are unnecessary. If you want to localize, open the `IdentityRelationship.Domain.Shared` project and create a new localization in your `/Localization/IdentityRelationship/en.json` file. @@ -73,27 +73,154 @@ Once you define a property, it appears in the create and update forms of the rel It is supported to add an extension property to an entity that is Id of another entity (foreign key). +### Example: Let's associate a department in the database with a user. +First create a `Departments` folder in the `IdentityRelationship.Domain` project and add the `Department` class inside. ```csharp -ObjectExtensionManager.Instance.Modules() - .ConfigureIdentity(identity => +using System; +using Volo.Abp.Domain.Entities; + +namespace IdentityRelationship.Departments; + +public class Department : AggregateRoot +{ + public string Name { get; set; } +} +``` + +EF Core requires that you relate the entities with your DbContext. The easiest way to do so is adding a DbSet property to the IdentityRelationshipDbContext class in the IdentityRelationship.EntityFrameworkCore project, as shown below: + +```csharp + public DbSet Departments { get; set; } +``` + +Then in the `IdentityRelationship.EntityFrameworkCore` project of your solution, open the `/EntityFrameworkCore/IdentityRelationshipEfCoreEntityExtensionMappings` class and update your code: + +```csharp +public static class IdentityRelationshipEfCoreEntityExtensionMappings +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() { - identity.ConfigureUser(user => + IdentityRelationshipGlobalFeatureConfigurator.Configure(); + IdentityRelationshipModuleExtensionConfigurator.Configure(); + + OneTimeRunner.Run(() => { - user.AddOrUpdateProperty( - "DepartmentId", - property => - { - property.UI.Lookup.Url = "/api/app/departments"; - property.UI.Lookup.DisplayPropertyName = "name"; - } - ); + ObjectExtensionManager.Instance + .MapEfCoreProperty( + "DepartmentId", + (entityBuilder, propertyBuilder) => { propertyBuilder.HasMaxLength(128); } + ); + }); - }); + } +} +``` + +This class can be used to map these extra properties to table fields in the database. Please read [this](https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities?_ga=2.21022651.140118448.1679289046-1173891759.1672473062) article to improve your understanding of what we are doing. + +We need to create a new migration to see the changes in the database. Open your EntityFrameworkCore project in the terminal (this depends on the IDE you are using). + +![terminal-image](images/open-terminal.png) + +```bash +dotnet ef migrations add Create_Department_Entity +``` + +Finally, run the `IdentityRelationship.DbMigrator` project to update the database. + +When you look at your database, you can see that `Department` table has been added and `DepartmentId` has been added to your `AbpUsers` table. + +![database-tables](images/database-tables.png) + +![users-table](images/users-table.png) + +Again open the `IdentityRelationshipModuleExtensionConfigurator` class in the Domain.Shared project and add the following code: + +```csharp + +user.AddOrUpdateProperty( + "DepartmentId", + property => + { + property.UI.Lookup.Url = "/api/app/departments"; + property.UI.Lookup.DisplayPropertyName = "name"; + } +); ``` `UI.Lookup.Url` option takes a URL to get list of departments to select on edit/create forms. This endpoint can be a typical controller, an auto API controller or any type of endpoint that returns a proper JSON response. +Create a `Departments` folder in the `IdentityRelationship.Application.Contracts` project of your solution and add the `DepartmentDto` class in it + +```csharp +using System; +namespace IdentityRelationship.Departments; + +public class DepartmentDto +{ + public Guid Id { get; set; } + + public string Name { get; set; } +} +``` +Now let's create an `IDepartmentAppService`interface in the `Departments` folder + +```csharp +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace IdentityRelationship.Departments; + +public interface IDepartmentAppService : IApplicationService +{ + public Task> GetAsync(); +} +``` + +Time to implement the `IDepartmentAppService` interface. Create a `Departments` folder in your `IdentityRelationship.Application` project and add the `DepartmentAppService` class inside. + +```csharp +using System; +using System.Threading.Tasks; +using IdentityRelationship.Departments; +using Volo.Abp.Application.Dtos; + +namespace IdentityRelationship.Department; + +public class DepartmentAppService : IdentityRelationshipAppService, IDepartmentAppService +{ + public async Task> GetAsync() + { + return new ListResultDto( + new[] + { + new DepartmentDto + { + Id = Guid.Parse("6267f0df-870f-4173-be44-d74b4b56d2bd"), + Name = "Human Resources" + }, + new DepartmentDto + { + Id = Guid.Parse("21c7b61f-330c-489e-8b8c-80e0a78a5cc5"), + Name = "Production" + } + } + ); + } +} +``` +Run your `IdentityRelationship.Web` project and add a department to one of your users. + +![user-department-image](images/user-department.png) + +And shows the department name on the data table: + +![users-page-department-image](images/users-page-department.png) + diff --git a/docs/en/Community-Articles/onur-article/images/database-tables.png b/docs/en/Community-Articles/onur-article/images/database-tables.png new file mode 100644 index 0000000000..a1cef0bc26 Binary files /dev/null and b/docs/en/Community-Articles/onur-article/images/database-tables.png differ diff --git a/docs/en/Community-Articles/onur-article/images/open-terminal.png b/docs/en/Community-Articles/onur-article/images/open-terminal.png new file mode 100644 index 0000000000..9f1069d02b Binary files /dev/null and b/docs/en/Community-Articles/onur-article/images/open-terminal.png differ diff --git a/docs/en/Community-Articles/onur-article/images/user-department.png b/docs/en/Community-Articles/onur-article/images/user-department.png new file mode 100644 index 0000000000..2d0a0d4416 Binary files /dev/null and b/docs/en/Community-Articles/onur-article/images/user-department.png differ diff --git a/docs/en/Community-Articles/onur-article/images/users-page-department.png b/docs/en/Community-Articles/onur-article/images/users-page-department.png new file mode 100644 index 0000000000..4ec8ef7d54 Binary files /dev/null and b/docs/en/Community-Articles/onur-article/images/users-page-department.png differ diff --git a/docs/en/Community-Articles/onur-article/images/users-table.png b/docs/en/Community-Articles/onur-article/images/users-table.png new file mode 100644 index 0000000000..81b2cf90dd Binary files /dev/null and b/docs/en/Community-Articles/onur-article/images/users-table.png differ