ABP扩展实体的方法

233 阅读2分钟

扩展实体

在某些情况下你可能希望为依赖模块中定义的实体添加一些额外的属性(和数据库字段).

方法1 Extra Properties

Extra properties是一种存储实体的一些额外数据但不用更改实体的方式. 实体应该实现 IHasExtraProperties 接口. 所有预构建模块定义的聚合根实体都实现了 IHasExtraProperties 接口,所以你可以在这些实体中存储额外的属性.

//SET AN EXTRA PROPERTY
var user = await _identityUserRepository.GetAsync(userId);
user.SetProperty("Title", "My custom title value!");
await _identityUserRepository.UpdateAsync(user);

//GET AN EXTRA PROPERTY
var user = await _identityUserRepository.GetAsync(userId);
return user.GetProperty<string>("Title");

这种方法开箱即用并且非常简单,你可以使用不同的属性名称(如这里的Title)在同一时间存储多个属性.

对于EF Core额外的属性被格式化成单个 JSON 字符值串存储在数据库中. 对于MongoDB它们做为单独的字段存储.

方法2 实体扩展 (EF Core)

如上所述,实体所有的额外属性都作为单个JSON对象存储在数据库表中. 它不适用复杂的场景,特别是在你需要的时候.

  • 使用额外属性创建索引外键.
  • 使用额外属性编写SQLLINQ(例如根据属性值搜索).
  • 创建你自己的实体映射到相同的表,但在实体中定义一个额外属性做为 常规属性

为了解决上面的问题,用于EF Core的ABP框架实体扩展系统允许你使用上面定义相同的额外属性API,但将所需的属性存储在单独的数据库表字段中.

假设你想要添加 SocialSecurityNumber 到身份模块的 IdentityUser 实体. 你可以使用 ObjectExtensionManager 类:

// IdentityUser 作为实体名(泛型参数), string 做为新属性的类型, 
//SocialSecurityNumber 做为属性名(也是数据库表的字段名).
ObjectExtensionManager.Instance
    .MapEfCoreProperty<IdentityUser, string>(
        "SocialSecurityNumber",
        (entityBuilder, propertyBuilder) =>
        {
            propertyBuilder.HasMaxLength(32);
        }
    );

必须在使用相关的 DbContext 之前执行此代码. 应用程序启动模板定义了一个名为 YourProjectNameEfCoreEntityExtensionMappings 的静态类. 你可以在此类中定义扩展确保在正确的时间执行它. 否则你需要自己处理.

定义实体扩展后你需要使用EF Core的Add-Migration和Update-Database命令来创建code first迁移类并更新数据库.

然后你可以使用上一部分中定义的相同额外属性系统来操纵实体上的属性.