From 0f3b6bc0a5f16f3dfeb90f60ad6d9826fd116a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 22 May 2021 13:52:45 +0300 Subject: [PATCH] Completed the article. --- .../POST.md | 235 +++++++++++++++++- .../new-prop-on-table.png | Bin 0 -> 23840 bytes 2 files changed, 230 insertions(+), 5 deletions(-) create mode 100644 docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/new-prop-on-table.png diff --git a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md index 886fd0f8b1..f7cd17f631 100644 --- a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md +++ b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md @@ -2,6 +2,10 @@ This article shows how to remove the `EntityFrameworkCore.DbMigrations` project from your solution to have a single `DbContext` for your database mappings and code first migrations. +## Source Code + +You can find source of the example solution used in this article [here](https://github.com/abpframework/abp-samples/tree/master/UnifiedEfCoreMigrations). + ## Motivation If you create a new solution with **Entity Framework Core** as the database provider, you see two projects related to EF Core: @@ -26,14 +30,12 @@ If you want to make it in your solution with today, follow the steps in this art > If you are using **ABP Commercial**, ABP Suite code generation won't work correctly with the new design. In this case, we suggest to wait for the next version. -## All the Changes in one PR! - -I've created a new solution with v4.3, then made all the changes in a pull request, so you can see all the changes line by line. While this article will cover all, you may want to [check the changes done in this PR](https://github.com/abpframework/abp-samples/pull/88) if you have problems with the implementation. - ## The Steps Our goal to enable database migrations in the `EntityFrameworkCore` project, remove the `EntityFrameworkCore.DbMigrations` project and revisit the code depending on that package. +> I've created a new solution with v4.3, then made all the changes in a pull request, so you can see all the changes line by line. While this article will cover all, you may want to [check the changes done in this PR](https://github.com/abpframework/abp-samples/pull/88) if you have problems with the implementation. + ### 1) Add Microsoft.EntityFrameworkCore.Tools package to the EntityFrameworkCore project Add the following code into the `EntityFrameworkCore.csproj` file: @@ -224,6 +226,229 @@ dotnet ef database update Your database won't have any change, because the migration is just empty and does nothing. From now, you can create new migrations as you change your entities, just like you normally do. +All the changes are done. The next section explains how to add custom properties to entities of depending modules with this design. + ## The AppUser Entity & Custom Properties -TODO \ No newline at end of file +The database mapping logic, solution structure and migrations become much simpler and easier to manage with that new setup. + +As a drawback, we had to remove the `AppUser` entity, which was sharing the `AbpUsers` table with the `IdentityUser` entity of the Identity Module. Fortunately, ABP provides a flexible system to [extend existing entities](https://docs.abp.io/en/abp/latest/Module-Entity-Extensions) in case of you need to define some custom properties. In this section, I will show how to add a custom property to the `IdentityUser` entity and use it in your application code and database queries. + +I've done all the changes in this part as a single PR, so you may want to [check the changes done in this PR](https://github.com/abpframework/abp-samples/pull/89) if you have problems with the implementation. + +### Defining a Custom Property + +The application startup template provides a point to configure the custom properties for existing entities, which is located under `Domain.Shared` project, in the `...ModuleExtensionConfigurator.cs` (`...` standard for your project name) class. Open that class and add the following code into the `ConfigureExtraProperties` method: + +````csharp +ObjectExtensionManager.Instance.Modules() + .ConfigureIdentity(identity => + { + identity.ConfigureUser(user => + { + user.AddOrUpdateProperty( //property type: string + "SocialSecurityNumber", //property name + property => + { + //validation rules + property.Attributes.Add(new RequiredAttribute()); + property.Attributes.Add(new StringLengthAttribute(64)); + } + ); + }); + }); +```` + +After that setup, just run the application to see the new property on the Users table: + +![new-prop-on-table](new-prop-on-table.png) + +The new `SocialSecurityNumber` property will also be available on the create and edit modals with the validation rules. + +> See the [Module Entity Extensions](https://docs.abp.io/en/abp/latest/Module-Entity-Extensions) document to understand and control the new custom property with all the details. + +### Mapping to the Database Table + +By default, ABP saves all custom properties inside the `ExtraProperties` field as a single JSON object. If you prefer to create a table field for a custom property, you can configure it in the `...EfCoreEntityExtensionMappings.cs` (`...` standard for your project name) class in the `EntityFrameworkCore` project. You can write the following code inside this class (in the `OneTimeRunner.Run`): + +````csharp +ObjectExtensionManager.Instance + .MapEfCoreProperty( + "SocialSecurityNumber", + (entityBuilder, propertyBuilder) => + { + propertyBuilder.HasMaxLength(64).IsRequired().HasDefaultValue(""); + } + ); +```` + +After that, you can just run the following command in a command-line terminal to add a new database migration (in the directory of the `EntityFrameworkCore` project): + +````bash +dotnet ef migrations add Added_SocialSecurityNumber_To_IdentityUser +```` + +This will add a new migration class to your project. You can then run the following command (or run the `.DbMigrator` application) to apply changes to the database: + +````bash +dotnet ef database update +```` + +This will add a `SocialSecurityNumber` field to the `AbpUsers` table in the database. + +### Using Custom Properties in the Application Code + +Now, we can use `GetProperty` and `SetProperty` methods on the `IdentityUser` entity to work with the new property. The following code demonstrates to get/set the custom property: + +````csharp +public class MyUserService : ITransientDependency +{ + private readonly IRepository _userRepository; + + public MyUserService(IRepository userRepository) + { + _userRepository = userRepository; + } + + public async Task SetSocialSecurityNumberDemoAsync(string userName, string number) + { + var user = await _userRepository.GetAsync(u => u.UserName == userName); + user.SetProperty("SocialSecurityNumber", number); + await _userRepository.UpdateAsync(user); + } + + public async Task GetSocialSecurityNumberDemoAsync(string userName) + { + var user = await _userRepository.GetAsync(u => u.UserName == userName); + return user.GetProperty("SocialSecurityNumber"); + } +} +```` + +Tip: Using `SetProperty` and `GetProperty` with a string property name everywhere could be tedious and error-prone. I suggest you to create the following extension methods: + +````csharp +public static class MyUserExtensions +{ + public const string SocialSecurityNumber = "SocialSecurityNumber"; + + public static void SetSocialSecurityNumber(this IdentityUser user, string number) + { + user.SetProperty(SocialSecurityNumber, number); + } + + public static string GetSocialSecurityNumber(this IdentityUser user) + { + return user.GetProperty(SocialSecurityNumber); + } +} +```` + +Then we can change the previous demo method as shown below: + +````csharp +public async Task SetSocialSecurityNumberDemoAsync(string userName, string number) +{ + var user = await _userRepository.GetAsync(u => u.UserName == userName); + user.SetSocialSecurityNumber(number); //Using the new extension property + await _userRepository.UpdateAsync(user); +} + +public async Task GetSocialSecurityNumberDemoAsync(string userName) +{ + var user = await _userRepository.GetAsync(u => u.UserName == userName); + return user.GetSocialSecurityNumber(); //Using the new extension property +} +```` + +### Querying Based on a Custom Property + +You may want to query users based on `SocialSecurityNumber`. We will use Entity Framework's API to accomplish that. You have two options to use EF Core API in your application code: + +1. Reference to the [Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore) NuGet package from your project (domain or application layer, depending on where you want to use the EF Core API). +2. Create a [repository](https://docs.abp.io/en/abp/latest/Repositories) interface in the domain layer and implement it in your `EntityFrameworkCore` project. + +I will prefer the second approach, so I am defining a new repository interface in the `Domain` project: + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; + +namespace UnifiedContextsDemo.Users +{ + public interface IMyUserRepository : IRepository + { + Task FindBySocialSecurityNumber(string number); + } +} +```` + +Then implementing it in the `EntityFrameworkCore` project: + +````csharp +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using UnifiedContextsDemo.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Identity; + +namespace UnifiedContextsDemo.Users +{ + public class MyUserRepository + : EfCoreRepository, + IMyUserRepository + { + public MyUserRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async Task FindBySocialSecurityNumber(string number) + { + var dbContext = await GetDbContextAsync(); + return await dbContext.Set() + .Where(u => EF.Property(u, "SocialSecurityNumber") == number) + .FirstOrDefaultAsync(); + } + } +} +```` + +Tip: Use the constant instead of `SocialSecurityNumber` as a magic string. + +Now, I can use that repository method in my service by injecting the `IMyUserRepository`: + +````csharp +public class MyUserService : ITransientDependency +{ + private readonly IMyUserRepository _userRepository; + + public MyUserService(IMyUserRepository userRepository) + { + _userRepository = userRepository; + } + + //...other methods + + public async Task FindBySocialSecurityNumberDemoAsync(string number) + { + return await _userRepository.FindBySocialSecurityNumber(number); + } +} +```` + +I changed `IRepository` dependency to `IMyUserRepository`. + +## Conclusion + +With this article, I wanted to show you how to remove the `EntityFrameworkCore.DbMigrations` project from your solution to simplify your database mappings, database migrations and your application code. In the next version (4.4), this [will be](https://github.com/abpframework/abp/issues/8776) the default approach. + +### Source Code + +You can find source of the example solution used in this article [here](https://github.com/abpframework/abp-samples/tree/master/UnifiedEfCoreMigrations). \ No newline at end of file diff --git a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/new-prop-on-table.png b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/new-prop-on-table.png new file mode 100644 index 0000000000000000000000000000000000000000..f10deb85960a7803d818171e234954dcc6469900 GIT binary patch literal 23840 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 literal 0 HcmV?d00001