使用EFCore时如何将类的internal属性存入数据库且不对外公开
解决方案
EFCore 适配配置
EFCore 默认仅映射实体的 public 属性,你只需在同程序集内的 OnModelCreating 方法中显式配置 internal 属性即可完成映射,无需修改属性访问级别:
- 手动单实体配置
protected override void OnModelCreating(ModelBuilder builder) { // 原有表名约定配置保留 foreach (var entity in builder.Model.GetEntityTypes()) { entity.SetTableName(entity.DisplayName()); } // 显式配置 User 的 internal 属性 builder.Entity<User>(u => { u.Property(p => p.FirstName); u.Property(p => p.MiddleName); u.Property(p => p.LastName); u.Property(p => p.EmailId); u.Property(p => p.DateOfBirth); }); base.OnModelCreating(builder); }
- 通用自动映射配置(适配多实体、新增属性无需修改配置)
先定义扩展方法:
using System.Reflection; using Microsoft.EntityFrameworkCore.Metadata.Builders; public static class EntityMappingExtensions { public static void MapAllInternalProperties<TEntity>(this EntityTypeBuilder<TEntity> builder) where TEntity : class { // 筛选当前实体的所有 internal 实例属性 var internalProperties = typeof(TEntity) .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic) .Where(prop => prop.GetMethod != null && prop.GetMethod.IsAssembly); foreach (var prop in internalProperties) { builder.Property(prop.Name); } } }
在 OnModelCreating 中调用即可:
builder.Entity<User>().MapAllInternalProperties(); // 其他包含 internal 属性的实体同理调用即可
兼容 Dapper/原生 ADO.NET 方案
Dapper 配置
Dapper 默认也仅映射 public 属性,你可以在 Component.User.csproj 内部全局配置 Dapper 的类型映射规则,允许读取非 public 属性:
using Dapper; using System.Reflection; // 程序集初始化时执行一次即可 SqlMapper.SetTypeMap( typeof(User), new CustomPropertyTypeMap( typeof(User), (type, columnName) => type.GetProperty( columnName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ) ) );
如果有多个实体需要适配,可以批量遍历配置。
原生 ADO.NET 实现
直接在内部仓储逻辑中通过反射读取 internal 属性值构造参数即可:
var firstNameParam = new SqlParameter("@FirstName", typeof(User).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(user) ?? DBNull.Value );
访问封闭性保障
你当前的设计已经满足不对外暴露属性的要求:
User类本身为 internal,Component.User.csproj 外部无法直接访问该类型- 所有属性为 internal,只要不添加
[assembly: InternalsVisibleTo]特性授权外部程序集访问,外部无法读取或修改这些属性 - 外部仅能通过公开的
IUserRepository接口操作业务逻辑,不会直接接触实体内部结构
内容的提问来源于stack exchange,提问作者phougatv
相关产品推荐
相关产品推荐

