.net 6 efcore一个model映射到多张表(非使用IEntityTypeConfiguration)

现在有两张表,结构一模一样,我又不想创建两个一模一样的model,就想一个model映射到两张表
在这里插入图片描述
废话不多说直接上代码

  1. 安装依赖包
    在这里插入图片描述
  2. 创建model
namespace oneModelMultiTable.Model
{
    public class Test
    {
        public int id { get; set; }

        public string name { get; set; }

        public string tablename { get; set; }
    }
}
  1. 创建DBContext
    我们需要使用tablename 动态指定表名,因此需要在DBContext中添加这个属性
namespace oneModelMultiTable
{
    public class DBHelper:DbContext
    {
        public DbSet<Test> testConfigs { get; set; }

        public string tablename { get; set; }
        public DBHelper(DbContextOptions<DBHelper> options):base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Test>(b =>
            {
                b.ToTable(tablename);
                b.HasKey(p => p.id);
            });

            base.OnModelCreating(modelBuilder);

            //modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

  1. 创建DynamicModelCacheKeyFactory 继承IModelCacheKeyFactory
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace oneModelMultiTable
{
    public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
    {

        public object Create(DbContext context, bool designTime)
        {
            object p = context is DBHelper dynamicContext
                ? (context.GetType(), dynamicContext.tablename)
                : (object)context.GetType();
            return p;
        }
    }
}
  1. 依赖注入
builder.Services.AddDbContext<DBHelper>(options =>
{
    options.UseNpgsql(@"Host=192.168.214.133;Port=32222;Database=postgresdb;Username=postgresadmin;Password=admin123")
    .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
});
  1. 创建controller
using Microsoft.AspNetCore.Mvc;
using oneModelMultiTable.Model;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace oneModelMultiTable.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        public readonly DBHelper dBHelper;

        public TestController(DBHelper _DBHelper)
        {
            dBHelper = _DBHelper;
        }

        // GET: api/<TestController>
        [HttpGet]
        public List<Test> Get(string tablename)
        {
            dBHelper.tablename = tablename;
            return dBHelper.testConfigs.ToList();
        }
    }
}

原理
你可能想通过ToTable()方法来更改表名,但是我们如何在OnModelCreating方法中更改表名呢?当EF构建模型时,它只运行OnModelCreating一次。

对于这个场景,我们需要通过使用IModelCacheKeyFactory来更改默认映射,它允许我们连接到模型缓存机制,以便EF可以根据其属性创建不同的模型。
EF使用IModelCacheKeyFactory为模型生成缓存键。

https://yanxiaodi.medium.com/mapping-the-model-to-multiple-tables-with-entityframework-core-b46bdeed8661

https://medium.com/@pawel.gerr/entity-framework-core-changing-database-schema-at-runtime-dcf1211768c6

https://github.com/xdqt/asp.net-core/tree/master/oneModelMultiTable

好的,这里给出一个使用AOP实现记录多张表数据变化的示例,包括批量添加、批量修改和批量删除操作。 1. 定义一个注解,用于标记需要记录数据变化的方法。例如: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RecordDataChange { String[] tables(); // 需要记录数据变化的表名 } ``` 2. 使用AOP拦截带有注解的方法,并记录数据变化。例如: ```java @Aspect @Component public class DataChangeAspect { @Autowired private DataChangeService dataChangeService; @Before("@annotation(recordDataChange)") public void before(JoinPoint joinPoint, RecordDataChange recordDataChange) { // 获取需要记录数据变化的表名 String[] tables = recordDataChange.tables(); // 获取方法参数 Object[] args = joinPoint.getArgs(); // 记录数据变化 for (String table : tables) { // 判断操作类型 if (joinPoint.getSignature().getName().startsWith("add")) { // 批量添加 List<?> dataList = (List<?>) args[0]; dataChangeService.recordBatchAdd(table, dataList); } else if (joinPoint.getSignature().getName().startsWith("update")) { // 批量修改 List<?> dataList = (List<?>) args[0]; dataChangeService.recordBatchUpdate(table, dataList); } else if (joinPoint.getSignature().getName().startsWith("delete")) { // 批量删除 List<?> idList = (List<?>) args[0]; dataChangeService.recordBatchDelete(table, idList); } } } } ``` 3. 在需要记录数据变化的方法上加上注解并指定需要记录数据变化的表名。例如: ```java @RecordDataChange(tables = {"user", "role"}) public void batchAddUserAndRole(List<User> userList, List<Role> roleList) { userDao.batchAdd(userList); roleDao.batchAdd(roleList); } ``` 这样,在调用`batchAddUserAndRole`方法时,会自动记录`user`表和`role`表的数据变化。当然,需要根据实际情况修改代码。 需要注意的是,以上示例只是一个简单的实现,具体实现方法需要根据具体业务场景进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值