我有一个带有特定表的遗留数据库 - 我将其称为ItemTable - 可能有数十亿行数据。为了克服数据库限制,我们决定在行数达到100,000,000时将表拆分为“孤岛”。因此,ItemTable将存在,然后一个过程将在半夜运行以检查行数。如果numberOfRows是>然后将创建100,000,000,然后创建silo1_ItemTable。从现在开始添加到数据库的任何项目都将添加到silo1_ItemTable(直到它变大,然后silo2_ItemTable将存在...)
ItemTable和silo1_ItemTable可以映射到同一个Item实体,因为表结构相同,但我不确定如何在运行时设置此映射,或者如何为查询指定表名。应将所有插入添加到最新的siloX_ItemTable中,并且所有读取应来自指定的siloX_ItemTable。
我有一个单独的siloTracker表,它将为我提供插入/读取数据的表名,但我不确定如何在实体框架中使用它...
思想?
答案 0 :(得分:2)
您可以尝试使用实体继承来获取此功能。因此,您有一个基类,其所有字段都映射到ItemTable,然后您有从ItemTable实体继承的后代类,并映射到db中的silo表。每次创建新的竖井时,都会创建映射到该竖井表的新实体。
[Table("ItemTable")]
public class Item
{
//All the fields in the table goes here
}
[Table("silo1_ItemTable")]
public class Silo1Item : Item
{
}
[Table("silo2_ItemTable")]
public class Silo2Item : Item
{
}
您可以找到有关此here
的更多信息其他选项是创建一个视图,该视图创建所有这些表的并集,并将您的实体映射到该视图。
答案 1 :(得分:0)
正如我在评论中提到的,为了解决这个问题,我使用的是DBSet公开的SQLQuery方法。由于我的所有项表都具有完全相同的模式,因此我可以使用SQLQuery来定义自己的查询,并且可以将表的名称传递给查询。在我的系统上测试过,它运行良好。
有关使用实体框架运行原始查询的说明,请参阅此链接: EF raw query documentation
如果有人有更好的方法来解决我的问题,请发表评论。
[UPDATE]
我同意存储过程也是一个很好的选择,但由于某种原因,我的管理层非常不愿意对我们的数据库进行任何更改。我(和我们的客户)更容易将sql放在代码中并承认存在原始sql的事实。至少我可以很容易地将它从其他层隐藏起来。
[/更新]
答案 2 :(得分:0)
此问题的可能解决方案可能是使用DbCompiledModel参数的上下文初始化:
var builder = new DbModelBuilder(DbModelBuilderVersion.V6_0);
builder.Configurations.Add(new EntityTypeConfiguration<EntityName>());
builder.Entity<EntityName>().ToTable("TableNameDefinedInRuntime");
var dynamicContext = new MyDbContext(builder.Build(context.Database.Connection).Compile());
由于某些原因,在EF6中,它在第二个表请求上失败,但在执行的那一刻,上下文中的映射看起来是正确的。