我们的组织需要拥有一个数据库,多租户
(通过表模式,而不是租户ID)架构.
这里有一篇很棒的文章来开始讨论这类事情:http: //romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/
在文章的中间,写道:
您会注意到(可能有点沮丧)我们需要编写代码来为每个实体配置表模式.不可否认,围绕此代码的魔术独角兽并不多......在EF的未来版本中,我们将能够用更清洁的自定义约定来替换它.
我们的目标是拥有一个最简单的方法,可以使用一个上下文类来连接到具有相同模型的多个模式.
(请注意,modelBuilder.HasDefaultSchema似乎不够,因为它仅适用于EF首次初始化上下文并运行OnModelCreating时)
EF5或EF6中是否存在上述清洁自定义约定?
或者是否有更清洁的方式来处理这个?
注意:我也在开发论坛上问了这个问题,因为它似乎更多地与EF的方向有关,但是想看看这里是否有人有替代方案.
注2:我不担心迁移,我们会分开处理.
我的数据库具有不同的模式,具体取决于运行时的用户选择
我的代码如下:
public partial class FashionContext : DbContext
{
private string _schema;
public FashionContext(string schema) : base()
{
_schema = schema;
}
public virtual DbSet<Style> Styles { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(@"Server=.\sqlexpress;Database=inforfashionplm;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Style>()
.ToTable("Style", schema: _schema);
}
}
Run Code Online (Sandbox Code Playgroud)
经过测试.我用'schema1'创建了一个上下文实例.到现在为止还挺好.
但是当我使用不同的模式'schema2'创建另一个上下文实例时,模式仍然在'schema1'上的结果数据.
这是实施:
using (var db = new FashionContext("schema1"))
{
foreach (var style in db.Styles)
{
Console.WriteLine(style.Name);
}
}
Console.ReadLine();
Console.Clear();
using (var db = new FashionContext("schema2"))
{
foreach (var …Run Code Online (Sandbox Code Playgroud) 故事:在我们的多租户应用程序(一个PostgreSql数据库,多个模式)中,我们需要对多个模式使用一个DbContext.
我尝试了什么:持有缓存(Dictionary,其中key是模式名称,value是该模式的上下文).在为另一个模式设置新上下文时,我可以看到dbContext模式仍然设置为提供的先前模式.我假设上下文中的模型是由上下文类型在内部缓存的,所以这就是我看到这种行为的原因?
所以上面似乎没有用,我发现实现IModelCacheKeyFactory应该可以解决问题.有谁知道应该怎么进入Create方法呢?任何地方都没有样品或文件.
我发现: 在Entity Framework Core中动态更改模式,但它为EF6提供了答案,因此帮助不大.
我有多个相同但内容不同的 SQL 服务器表。在编写代码第一个 EF6 程序时,我试图为每个程序重用相同的 db 上下文并将表名传递给上下文构造函数。
然而,虽然每次都调用构造函数,但 OnModelCreating 方法只被调用一次,尽管每次都从 new 创建 db 上下文。我该如何重置?
我曾尝试使用 AsNoTracking 并且我阅读了禁用 ModelCaching 的内容,但无法找到如何执行此操作或这是否是最佳方法。MSDN 甚至说“可以通过在给定的 ModelBuidler[sic] 上设置 ModelCaching 属性来禁用这种缓存”,但它不存在。
这是我的数据库上下文:
public partial class MissingContext : DbContext
{
private string tableName = "";
public MissingContext(string tableName) : base("name=MissingContext")
{
this.tableName = tableName;
}
public virtual DbSet<MissingData> MissingDataSet { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MissingData>()
.ToTable(this.tableName);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我使用它的代码:
List<MissingData> missingData=null;
string[] inputTables="TABLEA;TABLEB;TABLEC".Split(';');
foreach (string table in inputTables)
{
logger.Info($"Processing {table}");
missingData = …Run Code Online (Sandbox Code Playgroud) 我正在使用 .netCore 和实体框架从 SQL 数据库获取一些数据。
我已经设置了一个DbContext
public partial class DashboardContext : DbContext
{
public NotfallDashboardContext(DbContextOptions<NotfallDashboardContext> options) : base(options) {}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DashboardData>(entity =>
{
...
}
}
public virtual DbSet<DashboardData> DashboardData { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并使用以下设置将其注入我的控制器
services.AddDbContext<DashboardContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DashboardDatabase")));
Run Code Online (Sandbox Code Playgroud)
现在,该类DashboardData使用TableAttirbute 连接到正确的表和架构。
[Table("TableName", Schema = "dbo")]
public partial class DashboardData
{
...
}
Run Code Online (Sandbox Code Playgroud)
我想做的是将这两个字符串“TableName”和“dbo”提取到我的 appsettings.json 配置中。我已经将配置添加到 appsettings,创建了 TableConfiguration 类并设置依赖项注入:
表配置.cs
public class TableConfiguration
{
public string DatabaseView { get; set; } …Run Code Online (Sandbox Code Playgroud)