现在有两张表,结构一模一样,我又不想创建两个一模一样的model,就想一个model映射到两张表
废话不多说直接上代码
- 安装依赖包
- 创建model
namespace oneModelMultiTable.Model
{
public class Test
{
public int id { get; set; }
public string name { get; set; }
public string tablename { get; set; }
}
}
- 创建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);
}
}
}
- 创建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;
}
}
}
- 依赖注入
builder.Services.AddDbContext<DBHelper>(options =>
{
options.UseNpgsql(@"Host=192.168.214.133;Port=32222;Database=postgresdb;Username=postgresadmin;Password=admin123")
.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
});
- 创建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