diff --git a/build/common.ps1 b/build/common.ps1 index e4ba6a8adc..06fa20b35e 100644 --- a/build/common.ps1 +++ b/build/common.ps1 @@ -28,6 +28,7 @@ $solutionPaths = ( "../samples/BookStore-Modular/modules/book-management", "../samples/BookStore-Modular/application", "../samples/DashboardDemo", + "../samples/EfCoreMigrationDemo", "../samples/MicroserviceDemo", "../samples/RabbitMqEventBus", "../abp_io/AbpIoLocalization" diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Users/AppUser.cs b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Users/AppUser.cs index 9068cfbcd5..b746e68052 100644 --- a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Users/AppUser.cs +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Users/AppUser.cs @@ -41,9 +41,19 @@ namespace Acme.BookStore.Users #endregion /* Add your own properties here. Example: - * - * public virtual string MyProperty { get; set; } - */ + * + * public string MyProperty { get; set; } + * + * If you add a property and using the EF Core, remember these; + * + * 1. Update BookStoreDbContext.OnModelCreating + * to configure the mapping for your new property + * 2. Update BookStoreEfCoreEntityExtensionMappings to extend the IdentityUser entity + * and add your new property to the migration. + * 3. Use the Add-Migration to add a new database migration. + * 4. Run the .DbMigrator project (or use the Update-Database command) to apply + * schema change to the database. + */ private AppUser() { diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.Domain/Users/AppUser.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.Domain/Users/AppUser.cs index 9068cfbcd5..b746e68052 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.Domain/Users/AppUser.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.Domain/Users/AppUser.cs @@ -41,9 +41,19 @@ namespace Acme.BookStore.Users #endregion /* Add your own properties here. Example: - * - * public virtual string MyProperty { get; set; } - */ + * + * public string MyProperty { get; set; } + * + * If you add a property and using the EF Core, remember these; + * + * 1. Update BookStoreDbContext.OnModelCreating + * to configure the mapping for your new property + * 2. Update BookStoreEfCoreEntityExtensionMappings to extend the IdentityUser entity + * and add your new property to the migration. + * 3. Use the Add-Migration to add a new database migration. + * 4. Run the .DbMigrator project (or use the Update-Database command) to apply + * schema change to the database. + */ private AppUser() { diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs index 6a74deef7e..7d7b1cb243 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs @@ -42,13 +42,6 @@ namespace Acme.BookStore.EntityFrameworkCore builder.ConfigureTenantManagement(); builder.ConfigureBookManagement(); - /* Configure customizations for entities from the modules included */ - - builder.Entity(b => - { - b.ConfigureCustomUserProperties(); - }); - /* Configure your own tables/entities inside the ConfigureBookStore method */ builder.ConfigureBookStore(); diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs index 7212eb7340..dad059f971 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs @@ -11,6 +11,8 @@ namespace Acme.BookStore.EntityFrameworkCore { public BookStoreMigrationsDbContext CreateDbContext(string[] args) { + BookStoreEfCoreEntityExtensionMappings.Configure(); + var configuration = BuildConfiguration(); var builder = new DbContextOptionsBuilder() diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs index 85644bf40a..bfa602ef6b 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs @@ -3,6 +3,7 @@ using Acme.BookStore.Users; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.Abp.Identity; using Volo.Abp.Users.EntityFrameworkCore; namespace Acme.BookStore.EntityFrameworkCore @@ -39,12 +40,13 @@ namespace Acme.BookStore.EntityFrameworkCore builder.Entity(b => { - b.ToTable("AbpUsers"); //Sharing the same table "AbpUsers" with the IdentityUser + b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser b.ConfigureByConvention(); b.ConfigureAbpUser(); - //Moved customization to a method so we can share it with the BookStoreMigrationsDbContext class - b.ConfigureCustomUserProperties(); + /* Configure mappings for your additional properties + * Also see the BookStoreEfCoreEntityExtensionMappings class + */ }); /* Configure your own tables/entities inside the ConfigureBookStore method */ diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs index 1510809d5f..c132d297a4 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs @@ -1,7 +1,5 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Volo.Abp; -using Volo.Abp.Users; namespace Acme.BookStore.EntityFrameworkCore { @@ -20,11 +18,5 @@ namespace Acme.BookStore.EntityFrameworkCore // //... //}); } - - public static void ConfigureCustomUserProperties(this EntityTypeBuilder b) - where TUser: class, IUser - { - //b.Property(nameof(AppUser.MyProperty))... - } } } \ No newline at end of file diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs new file mode 100644 index 0000000000..cadfa73ccd --- /dev/null +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs @@ -0,0 +1,37 @@ +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace Acme.BookStore.EntityFrameworkCore +{ + public static class BookStoreEfCoreEntityExtensionMappings + { + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure entity extension properties for the + * entities defined in the used modules. + * + * The properties defined here becomes table fields. + * If you want to use the ExtraProperties dictionary of the entity + * instead of creating a new field, then define the property in the + * MyProjectNameDomainObjectExtensions class. + * + * Example: + * + * ObjectExtensionManager.Instance + * .MapEfCoreProperty( + * "MyProperty", + * b => b.HasMaxLength(128) + * ); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities + */ + }); + } + } +} \ No newline at end of file diff --git a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs index 5cb2a6dc7e..58999b2b0d 100644 --- a/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs +++ b/samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs @@ -29,6 +29,11 @@ namespace Acme.BookStore.EntityFrameworkCore )] public class BookStoreEntityFrameworkCoreModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreEfCoreEntityExtensionMappings.Configure(); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAbpDbContext(options => diff --git a/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEfCoreEntityExtensionMappings.cs b/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEfCoreEntityExtensionMappings.cs new file mode 100644 index 0000000000..d4358d0b66 --- /dev/null +++ b/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEfCoreEntityExtensionMappings.cs @@ -0,0 +1,36 @@ +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace Acme.BookStore.BookManagement.EntityFrameworkCore +{ + public static class BookManagementEfCoreEntityExtensionMappings + { + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure entity extension properties for the + * entities defined in the used modules. + * + * The properties defined here becomes table fields. + * If you want to use the ExtraProperties dictionary of the entity + * instead of creating a new field, then define the property in the + * MyProjectNameDomainObjectExtensions class. + * + * Example: + * + * ObjectExtensionManager.Instance + * .MapEfCoreProperty( + * "MyProperty", + * b => b.HasMaxLength(128) + * ); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities + */ + }); + } + } +} \ No newline at end of file diff --git a/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEntityFrameworkCoreModule.cs b/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEntityFrameworkCoreModule.cs index c2b2867938..758486bf7e 100644 --- a/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEntityFrameworkCoreModule.cs +++ b/samples/BookStore-Modular/modules/book-management/src/Acme.BookStore.BookManagement.EntityFrameworkCore/EntityFrameworkCore/BookManagementEntityFrameworkCoreModule.cs @@ -10,6 +10,11 @@ namespace Acme.BookStore.BookManagement.EntityFrameworkCore )] public class BookManagementEntityFrameworkCoreModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookManagementEfCoreEntityExtensionMappings.Configure(); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAbpDbContext(options => diff --git a/samples/BookStore/src/Acme.BookStore.Domain/Users/AppUser.cs b/samples/BookStore/src/Acme.BookStore.Domain/Users/AppUser.cs index 9068cfbcd5..b746e68052 100644 --- a/samples/BookStore/src/Acme.BookStore.Domain/Users/AppUser.cs +++ b/samples/BookStore/src/Acme.BookStore.Domain/Users/AppUser.cs @@ -41,9 +41,19 @@ namespace Acme.BookStore.Users #endregion /* Add your own properties here. Example: - * - * public virtual string MyProperty { get; set; } - */ + * + * public string MyProperty { get; set; } + * + * If you add a property and using the EF Core, remember these; + * + * 1. Update BookStoreDbContext.OnModelCreating + * to configure the mapping for your new property + * 2. Update BookStoreEfCoreEntityExtensionMappings to extend the IdentityUser entity + * and add your new property to the migration. + * 3. Use the Add-Migration to add a new database migration. + * 4. Run the .DbMigrator project (or use the Update-Database command) to apply + * schema change to the database. + */ private AppUser() { diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs index 541a91a0fd..5287d6f535 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContext.cs @@ -40,13 +40,6 @@ namespace Acme.BookStore.EntityFrameworkCore builder.ConfigureFeatureManagement(); builder.ConfigureTenantManagement(); - /* Configure customizations for entities from the modules included */ - - builder.Entity(b => - { - b.ConfigureCustomUserProperties(); - }); - /* Configure your own tables/entities inside the ConfigureBookStore method */ builder.ConfigureBookStore(); diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs index da72e6fb21..52307142f4 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs @@ -11,6 +11,8 @@ namespace Acme.BookStore.EntityFrameworkCore { public BookStoreMigrationsDbContext CreateDbContext(string[] args) { + BookStoreEfCoreEntityExtensionMappings.Configure(); + var configuration = BuildConfiguration(); var builder = new DbContextOptionsBuilder() diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs index 386eb2623b..c2df7ee6d0 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs @@ -3,6 +3,7 @@ using Acme.BookStore.Users; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.Abp.Identity; using Volo.Abp.Users.EntityFrameworkCore; namespace Acme.BookStore.EntityFrameworkCore @@ -41,15 +42,16 @@ namespace Acme.BookStore.EntityFrameworkCore builder.Entity(b => { - b.ToTable("AbpUsers"); //Sharing the same table "AbpUsers" with the IdentityUser + b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser b.ConfigureFullAudited(); b.ConfigureExtraProperties(); b.ConfigureConcurrencyStamp(); b.ConfigureAbpUser(); - //Moved customization to a method so we can share it with the BookStoreMigrationsDbContext class - b.ConfigureCustomUserProperties(); + /* Configure mappings for your additional properties + * Also see the BookStoreEfCoreEntityExtensionMappings class + */ }); /* Configure your own tables/entities inside the ConfigureBookStore method */ diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs index 922793e029..f11ec0d00a 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs @@ -1,8 +1,6 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; -using Volo.Abp.Users; namespace Acme.BookStore.EntityFrameworkCore { @@ -21,11 +19,5 @@ namespace Acme.BookStore.EntityFrameworkCore b.Property(x => x.Name).IsRequired().HasMaxLength(128); }); } - - public static void ConfigureCustomUserProperties(this EntityTypeBuilder b) - where TUser: class, IUser - { - //b.Property(nameof(AppUser.MyProperty))... - } } } \ No newline at end of file diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs new file mode 100644 index 0000000000..cadfa73ccd --- /dev/null +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEfCoreEntityExtensionMappings.cs @@ -0,0 +1,37 @@ +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace Acme.BookStore.EntityFrameworkCore +{ + public static class BookStoreEfCoreEntityExtensionMappings + { + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure entity extension properties for the + * entities defined in the used modules. + * + * The properties defined here becomes table fields. + * If you want to use the ExtraProperties dictionary of the entity + * instead of creating a new field, then define the property in the + * MyProjectNameDomainObjectExtensions class. + * + * Example: + * + * ObjectExtensionManager.Instance + * .MapEfCoreProperty( + * "MyProperty", + * b => b.HasMaxLength(128) + * ); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities + */ + }); + } + } +} \ No newline at end of file diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs index 156a4207cb..3faeb576da 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs @@ -27,6 +27,11 @@ namespace Acme.BookStore.EntityFrameworkCore )] public class BookStoreEntityFrameworkCoreModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreEfCoreEntityExtensionMappings.Configure(); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAbpDbContext(options => diff --git a/samples/DashboardDemo/src/DashboardDemo.Domain/Users/AppUser.cs b/samples/DashboardDemo/src/DashboardDemo.Domain/Users/AppUser.cs index 2f2ba91689..43f40fed20 100644 --- a/samples/DashboardDemo/src/DashboardDemo.Domain/Users/AppUser.cs +++ b/samples/DashboardDemo/src/DashboardDemo.Domain/Users/AppUser.cs @@ -41,9 +41,19 @@ namespace DashboardDemo.Users #endregion /* Add your own properties here. Example: - * - * public virtual string MyProperty { get; set; } - */ + * + * public string MyProperty { get; set; } + * + * If you add a property and using the EF Core, remember these; + * + * 1. Update BookStoreDbContext.OnModelCreating + * to configure the mapping for your new property + * 2. Update DashboardDemoEfCoreEntityExtensionMappings to extend the IdentityUser entity + * and add your new property to the migration. + * 3. Use the Add-Migration to add a new database migration. + * 4. Run the .DbMigrator project (or use the Update-Database command) to apply + * schema change to the database. + */ private AppUser() { diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContext.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContext.cs index c94d27faf0..ccec84b7e1 100644 --- a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContext.cs +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContext.cs @@ -40,13 +40,6 @@ namespace DashboardDemo.EntityFrameworkCore builder.ConfigureFeatureManagement(); builder.ConfigureTenantManagement(); - /* Configure customizations for entities from the modules included */ - - builder.Entity(b => - { - b.ConfigureCustomUserProperties(); - }); - /* Configure your own tables/entities inside the ConfigureDashboardDemo method */ builder.ConfigureDashboardDemo(); diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs index 0773892abc..b9f1526ad4 100644 --- a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs @@ -11,6 +11,8 @@ namespace DashboardDemo.EntityFrameworkCore { public DashboardDemoMigrationsDbContext CreateDbContext(string[] args) { + DashboardDemoEfCoreEntityExtensionMappings.Configure(); + var configuration = BuildConfiguration(); var builder = new DbContextOptionsBuilder() diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContext.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContext.cs index 94ec22abb3..a5d0bdea2e 100644 --- a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContext.cs +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContext.cs @@ -3,6 +3,7 @@ using DashboardDemo.Users; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.Abp.Identity; using Volo.Abp.Users.EntityFrameworkCore; namespace DashboardDemo.EntityFrameworkCore @@ -39,15 +40,16 @@ namespace DashboardDemo.EntityFrameworkCore builder.Entity(b => { - b.ToTable("AbpUsers"); //Sharing the same table "AbpUsers" with the IdentityUser + b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser b.ConfigureFullAudited(); b.ConfigureExtraProperties(); b.ConfigureConcurrencyStamp(); b.ConfigureAbpUser(); - //Moved customization to a method so we can share it with the DashboardDemoMigrationsDbContext class - b.ConfigureCustomUserProperties(); + /* Configure mappings for your additional properties + * Also see the DashboardDemoEfCoreEntityExtensionMappings class + */ }); /* Configure your own tables/entities inside the ConfigureDashboardDemo method */ diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContextModelCreatingExtensions.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContextModelCreatingExtensions.cs index 60dae7c4cf..0a5d05f6bc 100644 --- a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContextModelCreatingExtensions.cs +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoDbContextModelCreatingExtensions.cs @@ -1,7 +1,5 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Volo.Abp; -using Volo.Abp.Users; namespace DashboardDemo.EntityFrameworkCore { @@ -20,11 +18,5 @@ namespace DashboardDemo.EntityFrameworkCore // //... //}); } - - public static void ConfigureCustomUserProperties(this EntityTypeBuilder b) - where TUser: class, IUser - { - //b.Property(nameof(AppUser.MyProperty))... - } } } \ No newline at end of file diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEfCoreEntityExtensionMappings.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEfCoreEntityExtensionMappings.cs new file mode 100644 index 0000000000..2e5ce4d0bf --- /dev/null +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEfCoreEntityExtensionMappings.cs @@ -0,0 +1,37 @@ +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace DashboardDemo.EntityFrameworkCore +{ + public static class DashboardDemoEfCoreEntityExtensionMappings + { + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure entity extension properties for the + * entities defined in the used modules. + * + * The properties defined here becomes table fields. + * If you want to use the ExtraProperties dictionary of the entity + * instead of creating a new field, then define the property in the + * MyProjectNameDomainObjectExtensions class. + * + * Example: + * + * ObjectExtensionManager.Instance + * .MapEfCoreProperty( + * "MyProperty", + * b => b.HasMaxLength(128) + * ); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities + */ + }); + } + } +} \ No newline at end of file diff --git a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs index de03726a20..043cf10197 100644 --- a/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs +++ b/samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs @@ -27,6 +27,11 @@ namespace DashboardDemo.EntityFrameworkCore )] public class DashboardDemoEntityFrameworkCoreModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + DashboardDemoEfCoreEntityExtensionMappings.Configure(); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAbpDbContext(options => diff --git a/samples/EfCoreMigrationDemo/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs b/samples/EfCoreMigrationDemo/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs index da72e6fb21..7364cd29ab 100644 --- a/samples/EfCoreMigrationDemo/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs +++ b/samples/EfCoreMigrationDemo/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs @@ -11,6 +11,7 @@ namespace Acme.BookStore.EntityFrameworkCore { public BookStoreMigrationsDbContext CreateDbContext(string[] args) { + var configuration = BuildConfiguration(); var builder = new DbContextOptionsBuilder() diff --git a/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/Acme.BookStore.EntityFrameworkCore.Tests.csproj b/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/Acme.BookStore.EntityFrameworkCore.Tests.csproj index dd2137ad06..b03b0ed22d 100644 --- a/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/Acme.BookStore.EntityFrameworkCore.Tests.csproj +++ b/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/Acme.BookStore.EntityFrameworkCore.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/EntityFrameworkCore/BookStoreEntityFrameworkCoreTestModule.cs b/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/EntityFrameworkCore/BookStoreEntityFrameworkCoreTestModule.cs index e1171d6d90..a3f2bb5aa7 100644 --- a/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/EntityFrameworkCore/BookStoreEntityFrameworkCoreTestModule.cs +++ b/samples/EfCoreMigrationDemo/test/Acme.BookStore.EntityFrameworkCore.Tests/EntityFrameworkCore/BookStoreEntityFrameworkCoreTestModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Data.Sqlite; +using Acme.BookStore.DbMigrationsForSecondDb.EntityFrameworkCore; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; @@ -51,6 +52,15 @@ namespace Acme.BookStore.EntityFrameworkCore context.GetService().CreateTables(); } + var secondOptions = new DbContextOptionsBuilder() + .UseSqlite(connection) + .Options; + + using (var context = new BookStoreSecondMigrationsDbContext(secondOptions)) + { + context.GetService().CreateTables(); + } + return connection; } } diff --git a/samples/EfCoreMigrationDemo/test/Acme.BookStore.Web.Tests/BookStoreWebTestModule.cs b/samples/EfCoreMigrationDemo/test/Acme.BookStore.Web.Tests/BookStoreWebTestModule.cs index 46e4312035..786015d18b 100644 --- a/samples/EfCoreMigrationDemo/test/Acme.BookStore.Web.Tests/BookStoreWebTestModule.cs +++ b/samples/EfCoreMigrationDemo/test/Acme.BookStore.Web.Tests/BookStoreWebTestModule.cs @@ -12,6 +12,7 @@ using Acme.BookStore.Web; using Acme.BookStore.Web.Menus; using Volo.Abp; using Volo.Abp.AspNetCore.TestBase; +using Volo.Abp.Data; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.UI.Navigation; @@ -38,6 +39,13 @@ namespace Acme.BookStore { ConfigureLocalizationServices(context.Services); ConfigureNavigationServices(context.Services); + + Configure(options => + { + //SqliteConnection does not support nested transactions. + //So Dbcontext and connectionString need be same. + options.ConnectionStrings.Clear(); + }); } private static void ConfigureLocalizationServices(IServiceCollection services) diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs index cd5c8dbb3d..1b5b3996ee 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs @@ -46,7 +46,7 @@ namespace MyCompanyName.MyProjectName.Users * * If you add a property and using the EF Core, remember these; * - * 1. update MyProjectNameDbContext.OnModelCreating + * 1. Update MyProjectNameDbContext.OnModelCreating * to configure the mapping for your new property * 2. Update MyProjectNameEfCoreEntityExtensionMappings to extend the IdentityUser entity * and add your new property to the migration.