1

我有一个带有特定表的遗留数据库——我称之为 ItemTable——它可以有数十亿行数据。为了克服数据库限制,我们决定在行数达到 100,000,000 时将表拆分为“孤岛”。所以,ItemTable 会存在,然后会在半夜运行一个程序来检查行数。如果 numberOfRows > 100,000,000 则将创建 silo1_ItemTable。从现在开始添加到数据库中的任何项目都将添加到 silo1_ItemTable (直到它变大,然后 silo2_ItemTable 将存在......)

ItemTable 和 silo1_ItemTable 可以映射到同一个 Item 实体,因为表结构是相同的,但我不确定如何在运行时设置此映射,或者如何为我的查询指定表名。所有插入都应该添加到最新的 siloX_ItemTable 中,并且所有 Reads 都应该来自指定的 siloX_ItemTable。

我有一个单独的 siloTracker 表,它将为我提供用于插入/读取数据的表名,但我不确定如何将它与实体框架一起使用......

想法?

4

3 回答 3

2

您可以尝试使用实体继承来获得它。所以你有一个基类,它的所有字段都映射到 ItemTable,然后你有继承自 ItemTable 实体并映射到数据库中的筒仓表的后代类。每次创建新筒仓时,都会创建一个映射到该筒仓表的新实体。

 [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
{

}

您可以在此处找到更多信息

其他选项是创建一个视图,该视图创建所有这些表的联合并将您的实体映射到该视图。

于 2013-06-14T20:33:45.963 回答
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 中它在第二个表请求时失败,但在执行时上下文内部的映射看起来是正确的。

于 2014-11-20T03:19:02.200 回答
0

正如我在评论中提到的,为了解决这个问题,我使用了 DBSet 公开的 SQLQuery 方法。由于我所有的项目表都具有完全相同的架构,因此我可以使用 SQLQuery 来定义我自己的查询,并且可以将表的名称传递给查询。在我的系统上测试,它运行良好。

有关使用实体框架运行原始查询的说明,请参阅此链接: EF 原始查询文档

如果有人有更好的方法来解决我的问题,请发表评论。

[更新]

我同意存储过程也是一个不错的选择,但出于某种原因,我的管理层非常反对对我们的数据库进行任何更改。我(和我们的客户)更容易将 sql 放入代码中并承认存在原始 sql 的事实。至少我可以很容易地将它隐藏在其他图层中。

[/更新]

于 2013-06-17T15:04:22.827 回答