当前位置: 首页 > news >正文

先建网站还是先做网页网站建设合同的结构

先建网站还是先做网页,网站建设合同的结构,tk域名注册网站,新平台怎么推广原文#xff1a;Unifying DbContexts for EF Core / Removing the EF Core Migrations Project[1]导读#xff1a;软件开发的一切都需要平衡在 ABP Framework V4.4 RC 新增功能介绍 中#xff0c;对应用程序启动解决方案模板做了一个重要改变#xff1a;删除 EntityFramewo… 原文Unifying DbContexts for EF Core / Removing the EF Core Migrations Project[1]导读软件开发的一切都需要平衡在 ABP Framework V4.4 RC 新增功能介绍 中对应用程序启动解决方案模板做了一个重要改变删除 EntityFrameworkCore.DbMigrations 项目。本文将详细解读背后的原因和解决方案。1.理解动机很重要为什么先前的版本要将要数据上下文进行分离而现在为什么要合并2.合并之后存在什么缺陷以及如何解决这篇文件演示如何将解决方案中 EntityFrameworkCore.DbMigrations 项目移除并实现使用 单个 DbContext 进行数据实体映射和数据迁移。本篇文章项目源码[3]关注 ABP Framework 最新开发进度后面还会陆续发布新功能详解、新功能示例等系列文章敬请关注 ABP Framework 研习社QQ群726299208 专注 ABP Framework 学习经验分享、问题讨论、示例源码、电子书共享欢迎加入动机如果使用启动模板生成解决方案数据库提供程序是 Entity Framework Core那么在解决方案中会存在依赖 EF Core的两个项目•.EntityFrameworkCore•.EntityFrameworkCore.DbMigrations.EntityFrameworkCore项目包含应用程序真实的 DbContext**、数据库映射和仓储实现**。.EntityFrameworkCore.DbMigrations项目包含另一个 DbContext 只用于创建和数据迁移。包含所有正在使用的模块的数据实体映射生成统一的数据库表结构。分离的原因有两个1.让真实 DbContext 保持简单和专注。只包含当前项目相关的实体而与在应用程序使用的模块的实体和数据上下文无关因为每个模块都有自己的 DbContext 而将模型创建方法单独放在 EntityFrameworkCore.DbMigrations 项目中。2.复用依赖模块中的表通过创建自己的类映射到依赖模块中的表。举例自定义 AppUser 实体映射到数据库中 AbpUsers 表实际上该表由 Identity 模块[4] 的 IdentityUser 实体映射生成。他们共用相同的数据库表。和 IdentityServer 实体相比 AppUser 包含的属性更少可以根据需要在 AppUser 中添加所需的属性只需要设置好数据库映射新增字段会添加到映射表中。我们详细的描述了这种结构[5]。然而对于开发者仍然存在问题因为当需要复用依赖模块中的表时这种结构会使的数据实体映射变得复杂。许多开发者在映射这些类时容易产生误解或犯错特别是当试图使用的实体与其他实体存在关联关系时。所以我们在 V4.4 版本中决定取消这种分离删除 EntityFrameworkCore.DbMigrations 项目。新的启动方案将带只有一个 EntityFrameworkCore 项目和一个 DbContext 类。如果你想在你的解决方案中加入今天的内容请遵循本文的步骤。警告新的设计有一个缺点。我们必须删除 AppUser 实体因为不能在同一个 DbContext 中很好地处理没有继承关系的两个类映射到同一张表中。在本文的后面会介绍这个问题并提供处理它的建议。如果您使用 ABP Commercial 商业版ABP套件代码生成功能还不会采用本文中提到的设计方法建议等待下一个版本。步骤我们的目标是删除 EntityFrameworkCore.DbMigrations 项目在 EntityFrameworkCore 项目中启用数据库迁移替换迁移项目的依赖。原解决方案是基于 v4.3 创建一个新的解决方案然后在 pull request 中记录所有的修改所以你可以逐行看到所有的修改。虽然这篇文章将涵盖所有的内容但如果你在实现过程中遇到问题你可能想检查这个PR中所做的修改[6]。第一步添加 Microsoft.EntityFrameworkCore.Tools 包到 EntityFrameworkCore 项目将下面代码添加到 EntityFrameworkCore.csproj 文件ItemGroupPackageReference IncludeMicrosoft.EntityFrameworkCore.Tools Version5.0.*IncludeAssetsruntime; build; native; contentfiles; analyzers/IncludeAssetsPrivateAssetscompile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native/PrivateAssets/PackageReference /ItemGroup 第二步创建设计时 DbContext 工厂在 EntityFrameworkCore 项目中创建实现 IDesignTimeDbContextFactoryT 接口的数据上下文工厂using System.IO; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration;namespace UnifiedContextsDemo.EntityFrameworkCore {public class UnifiedContextsDemoDbContextFactory : IDesignTimeDbContextFactoryUnifiedContextsDemoDbContext{public UnifiedContextsDemoDbContext CreateDbContext(string[] args){UnifiedContextsDemoEfCoreEntityExtensionMappings.Configure();var configuration BuildConfiguration();var builder new DbContextOptionsBuilderUnifiedContextsDemoDbContext().UseSqlServer(configuration.GetConnectionString(Default));return new UnifiedContextsDemoDbContext(builder.Options);}private static IConfigurationRoot BuildConfiguration(){var builder new ConfigurationBuilder().SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), ../UnifiedContextsDemo.DbMigrator/)).AddJsonFile(appsettings.json, optional: false);return builder.Build();}} } 基本上是从 EntityFrameworkCore.DbMigrations 项目中复制的重命名并使用应用程序的实际 DbContext 。第三步创建 数据库模式迁移器复制 EntityFrameworkCore...DbSchemaMigrator省略号表示项目命名类到 EntityFrameworkCore 项目中修改 MigrateAsync 方法中的代码以使用真实 DbContext 。using System; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using UnifiedContextsDemo.Data; using Volo.Abp.DependencyInjection;namespace UnifiedContextsDemo.EntityFrameworkCore {public class EntityFrameworkCoreUnifiedContextsDemoDbSchemaMigrator: IUnifiedContextsDemoDbSchemaMigrator, ITransientDependency{private readonly IServiceProvider _serviceProvider;public EntityFrameworkCoreUnifiedContextsDemoDbSchemaMigrator(IServiceProvider serviceProvider){_serviceProvider serviceProvider;}public async Task MigrateAsync(){/* We intentionally resolving the UnifiedContextsDemoMigrationsDbContext* from IServiceProvider (instead of directly injecting it)* to properly get the connection string of the current tenant in the* current scope.*/await _serviceProvider.GetRequiredServiceUnifiedContextsDemoDbContext().Database.MigrateAsync();}} } 第四步 转移数据库实体映射配置在 迁移 DbContext 中包含 builder.ConfigureXXX() 对应每个使用的模块的数据实体映射配置。移动这些配置到 EntityFrameworkCore 项目的 真实 DbContext 中并移除 AppUser 数据库实体映射。可以选择将自己定义的实体数据库映射代码从...DbContextModelCreatingExtensions类中移到 真实 DbContext 的 OnModelCreating 方法中并删除该静态扩展类。示例解决方案中最终 DbContext 代码如下using Microsoft.EntityFrameworkCore; using UnifiedContextsDemo.Users; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.BackgroundJobs.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.IdentityServer.EntityFrameworkCore; using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.EntityFrameworkCore;namespace UnifiedContextsDemo.EntityFrameworkCore {[ConnectionStringName(Default)]public class UnifiedContextsDemoDbContext: AbpDbContextUnifiedContextsDemoDbContext{public DbSetAppUser Users { get; set; }/* Add DbSet properties for your Aggregate Roots / Entities here.* Also map them inside UnifiedContextsDemoDbContextModelCreatingExtensions.ConfigureUnifiedContextsDemo*/public UnifiedContextsDemoDbContext(DbContextOptionsUnifiedContextsDemoDbContext options): base(options){}protected override void OnModelCreating(ModelBuilder builder){base.OnModelCreating(builder);builder.ConfigurePermissionManagement();builder.ConfigureSettingManagement();builder.ConfigureBackgroundJobs();builder.ConfigureAuditLogging();builder.ConfigureIdentity();builder.ConfigureIdentityServer();builder.ConfigureFeatureManagement();builder.ConfigureTenantManagement();/* Configure your own tables/entities inside here *///builder.EntityYourEntity(b //{// b.ToTable(UnifiedContextsDemoConsts.DbTablePrefix YourEntities, UnifiedContextsDemoConsts.DbSchema);// b.ConfigureByConvention(); //auto configure for the base class props// //...//});}} } 第五步从解决方案中移除 EntityFrameworkCore.DbMigrations 项目从解决方案中移除 EntityFrameworkCore.DbMigrations 项目将对该项目的引用替换为 EntityFrameworkCore 项目引用。同样地将模块依赖 ...EntityFrameworkCoreDbMigrationsModule 替换为 ...EntityFrameworkCoreModule 。示例项目中涉及的项目为 DbMigrator Web 和 Web and EntityFrameworkCore.Tests 。第六步移除 AppUser 实体我们需要将 AppUser 这个实体移除因为 EF Core 不能两个非继承关系的类映射到单个表。所以删除这个类和所有的对该类的使用。如果你需要在应用程序代码中查询用户可以用 IdentityUser 替换。更多信息请参见 AppUser 实体和自定义属性部分。第七步创建数据迁移如果需要使用数据迁移历史记录可以直接将 EntityFrameworkCore.DbMigrations 项目中生成的 migrations 复制到 EntityFrameworkCore 项目并手动修改其中的 DbContext 类型。如果需要在已经应用了数据迁移的数据库中继续应用新的数据迁移在 EntityFrameworkCore 项目中创建新的数据库迁移执行命令dotnet ef migrations add InitialUnified 你可以指定一个不同的迁移名称这将创建一个迁移类其中包含你在数据库中已有的所有数据库表。注意删除 Up 和 Down 方法中的所有内容然后就可以将迁移应用到数据库中。dotnet ef database update 数据库不会有任何变化因为迁移是空的什么都不做。从现在开始可以在改变实体时创建新的迁移就像平时做的那样。DbContext 合并已经完成。接下来将解决如何基于这种设计为依赖模块的实体添加自定义属性。AppUser 实体 和自定义属性数据库映射逻辑、解决方案结构和数据迁移变得简单和易于管理。带来的弊端是我们必须移除 AppUser 实体因为其与 Identity 模块中 IdentityUser 实体共享 AbpUsers 表。幸运的是ABP提供了一个灵活的系统来 扩展现有的实体[7] 如果你需要定义一些自定义属性的话。在本节中我将展示如何向 IdentityUser 实体添加一个自定义属性并在你的应用程序代码和数据库查询中使用它。我已经把这部分的所有修改作为一个单独的PR完成了所以如果你在实现上有问题你可能想检查这个PR中的修改[8]。定义一个自定义属性应用程序启动模板提供一个配置点为实体添加自定义属性位于 Domain.Shared 项目中 ...ModuleExtensionConfigurator.cs 类在 ConfigureExtraProperties 方法中添加代码ObjectExtensionManager.Instance.Modules().ConfigureIdentity(identity {identity.ConfigureUser(user {user.AddOrUpdatePropertystring( //属性类型: stringSocialSecurityNumber, //属性名property {//validation rulesproperty.Attributes.Add(new RequiredAttribute());property.Attributes.Add(new StringLengthAttribute(64));});});}); 设置完成后只要运行应用程序就可以看到用户表上的新属性。新的SocialSecurityNumber属性也将在创建和编辑模式中应用添加的验证规则。参看 模块实体扩展[9] 文档理解和使用自定义属性。映射到数据库表ABP默认将所有自定义属性作为一个 Json 对象保存到 ExtraProperties 字段。如果要为自定义属性创建表字段可以在 EntityFrameworkCore 项目 ...EfCoreEntityExtensionMappings.cs 中配置在该类OneTimeRunner.Run中添加如下代码ObjectExtensionManager.Instance.MapEfCorePropertyIdentityUser, string(SocialSecurityNumber,(entityBuilder, propertyBuilder) {propertyBuilder.HasMaxLength(64).IsRequired().HasDefaultValue();}); 然后直接在 EntityFrameworkCore 项目中执行添加数据迁移命令dotnet ef migrations add Added_SocialSecurityNumber_To_IdentityUser 将在项目汇总添加一个新的数据迁移类接着可以通过运行 .DbMigrator 应用或如下命令应用修改到数据库dotnet ef database update 将会在数据库 AbpUsers 表中添加字段 SocialSecurityNumber 。使用自定义属性现在可以使用 IdentityUser 实体中 GetProperty 和 SetProperty 方法操作新添加的属性。下面示例代码演示如何获取和设置自定义属性public class MyUserService : ITransientDependency {private readonly IRepositoryIdentityUser, Guid _userRepository;public MyUserService(IRepositoryIdentityUser, Guid 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 Taskstring GetSocialSecurityNumberDemoAsync(string userName){var user await _userRepository.GetAsync(u u.UserName userName);return user.GetPropertystring(SocialSecurityNumber);} } 提示使用 SetProperty 和 GetProperty 使用字符串属性名可能会很繁琐而且容易出错。建议创建以下扩展方法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.GetPropertystring(SocialSecurityNumber);} } 然后我们可以改变之前的演示方法如下图所示。public async Task SetSocialSecurityNumberDemoAsync(string userName, string number) {var user await _userRepository.GetAsync(u u.UserName userName);user.SetSocialSecurityNumber(number); //Using the new extension propertyawait _userRepository.UpdateAsync(user); }public async Taskstring GetSocialSecurityNumberDemoAsync(string userName) {var user await _userRepository.GetAsync(u u.UserName userName);return user.GetSocialSecurityNumber(); //Using the new extension property } 基于自定义属性查询添加自定义属性之后我们可能需要基于自定义属性查询。是否可以基于 Entity Framework 的 API 来实现有两种方式实现在应用程序中使用EF Core API这与自定义属性无关与 EF Core有关。1.领域层或应用层引用 Microsoft.EntityFrameworkCore[10] Nuget包在那个项目中引用取决于你要在哪需要使用 EF Core API。DDD中数据提供程序无关性原则冲突2.在领域层创建仓储接口然后在 EntityFrameworkCore 项目中实现接口。推荐使用第二种方式在 Domain 项目中定义一个新的仓储接口using System; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; using Volo.Abp.Identity;namespace UnifiedContextsDemo.Users {public interface IMyUserRepository : IRepositoryIdentityUser, Guid{TaskIdentityUser FindBySocialSecurityNumber(string number);} } 在 EntityFrameworkCore 项目中实现接口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: EfCoreRepositoryUnifiedContextsDemoDbContext, IdentityUser, Guid,IMyUserRepository{public MyUserRepository(IDbContextProviderUnifiedContextsDemoDbContext dbContextProvider): base(dbContextProvider){}public async TaskIdentityUser FindBySocialSecurityNumber(string number){var dbContext await GetDbContextAsync();return await dbContext.SetIdentityUser().Where(u EF.Propertystring(u, SocialSecurityNumber) number).FirstOrDefaultAsync();}} } 提示应该使用一个常量代替SocialSecurityNumber魔术字符串。不会产生拼写错误现在我可以在应用服务中依赖注入 IMyUserRepository 使用仓储接口public class MyUserService : ITransientDependency {private readonly IMyUserRepository _userRepository;public MyUserService(IMyUserRepository userRepository){_userRepository userRepository;}//...other methodspublic async TaskIdentityUser FindBySocialSecurityNumberDemoAsync(string number){return await _userRepository.FindBySocialSecurityNumber(number);} } 使用自定义仓储接口 IMyUserRepository 代替泛型仓储接口 IRepositoryIdentityUser, Guid。讨论 Github这篇文章演示了如何将 EntityFrameworkCore.DbMigrations 项目从解决方案中移除以简化数据库实体映射、数据迁移和应用程序中的代码。在下一个版本4.4将作为默认处理。讨论Consider to remove EntityFrameworkCore.DbMigrations project from the solution #8776[11]References[1] Unifying DbContexts for EF Core / Removing the EF Core Migrations Project: https://community.abp.io/articles/unifying-dbcontexts-for-ef-core-removing-the-ef-core-migrations-project-nsyhrtna[2] ABP Framework V4.4 RC 新增功能介绍: https://www.cnblogs.com/YGYH/p/14973806.html[3] 项目源码: https://github.com/abpframework/abp-samples/tree/master/UnifiedEfCoreMigrations[4] Identity 模块: https://docs.abp.io/en/abp/latest/Modules/Identity[5] 描述了这种结构: https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Migrations[6] 这个PR中所做的修改: https://github.com/abpframework/abp-samples/pull/88[7] 扩展现有的实体: https://docs.abp.io/en/abp/latest/Module-Entity-Extensions[8] 检查这个PR中的修改: https://github.com/abpframework/abp-samples/pull/89[9] 模块实体扩展: https://docs.abp.io/en/abp/latest/Module-Entity-Extensions[10] Microsoft.EntityFrameworkCore: https://www.nuget.org/packages/Microsoft.EntityFrameworkCore[11] Consider to remove EntityFrameworkCore.DbMigrations project from the solution #8776: https://github.com/abpframework/abp/issues/8776
http://www.huolong8.cn/news/277646/

相关文章:

  • 做外贸网站公司哪家安徽网站建设公司哪家好
  • 网站建设分为几种网站建设与优化推广的话术
  • 百度竞价入门教程企业关键词排名优化哪家好
  • vps 内存影响 网站宁波网站推广平台咨询公司
  • 做网站枣庄怎么建立和设计公司网站
  • 秋长网站建设手机网站优化
  • 灯具电商网站建设方案网站设计与网站制作
  • wordpress 模块插件容城轻松seo优化排名
  • 济南网站制作创意忘记密码wordpress
  • 微网站模板源代码seo是啥职业
  • 河南网站seo地址网站建设外包需要注意哪些
  • 那些网站是静态给企业做网站推广好么
  • 住房城乡建设部执业资格注册中心网站岳阳网站建设设计
  • 小学网站asp网页设计规范模板
  • 个人怎样建网站赚钱云南省
  • 重庆江北营销型网站建设价格北京城乡与建设厅官方网站查询
  • 通州做网站公司硅云买域名做网站
  • 企业网站的在线推广方法有哪些公司简介怎么写 范文
  • 合肥网站维护陕西建设网查证件查询
  • 洮南住建局网站建设网站的基本流程
  • 丽水网站开发广告传媒公司简介
  • 北京市住房和城乡建设部网站官网wordpress消息通知
  • 自己建网站怎么做影视资源部队网站设计
  • 做体育网站想做网络推广如何去做
  • 重庆渝中区企业网站建设公司网络商城网站怎样做关键词优化
  • 网站设计画布规范1680网络营销课程报告
  • 个人网站 作品镜像的网站怎么做排名
  • 洛阳做网站的宽带多少钱一个月
  • 怎么在ps做网站首页宁波网页设计美工多少一个月
  • 网站建设是必须的吗标签用wordpress