我们有15个包含75个表的数据库,平均每百万行。全部具有相同的架构,但数据不同。现在,客户端已向我们提出了将全部15个数据库整合到一个数据库中的要求。用户登录过滤的每组数据。
对应用程序的更改已完成,可以进行过滤。现在剩下的任务是将所有数据库合并到一个数据库中。
问题是PK和FK冲突,因为PK和FK的类型为int,所以我们将有15个PK ID为1。
一种想法是使用。NET和DBML将记录作为新记录插入到新数据库中,从而使linq处理PK和FK,并使用代码处理重复数据。
还有什么其他方法可以做到这一点?
当记录在所有数据库中都没有唯一的主键时,集成数据库绝不是一件容易的事。几周前,我构建了一个类似的集成脚本,因此决定使用Entity Framework。
首先是好消息。使用EF的DbContext
API,插入一个完整的对象图并使EF将所有新生成的主键都当作外键来处理是非常容易的。之所以如此简单,是因为当一个对象的状态更改为Added
所有粘附对象时Added
,EF也会弄清楚插入的正确顺序。这真是太好了!它使我在几个小时内就建立了复制例程的核心,例如,如果我应该在T-SQL中完成复制,则可能要花很多天。后者也容易出错。
当然生活并不那么容易。现在的坏消息是:
这需要大量的机器资源。当然,我为每个复制步骤都使用了一个新的上下文实例,但是仍然必须在具有良好处理器和大量内部存储器的计算机上执行程序。确切的规格无关紧要,消息是:使用最大的数据库进行测试,并查看您需要哪种野兽。如果您无法使用任何机器来管理内存消耗,则必须将例程分成较小的块,但这将需要更多的编程。
更改为的对象图Added
必须是发散的。我的意思是,仅1-n
应从根开始进行关联。原因是,EF实际上会将所有对象标记为Added
。因此,如果图中的某个位置有几个分支引用回同一对象(因为存在n-1
关联),则这些“新”对象将被相乘,因为EF不知道它们的身份。这样的例子可能是Company -< Customer
-< Order
>- OrderType
:当只有2种订单类型时,插入一个拥有10个客户且每个订单10个的根公司,将创建100个订单类型记录,而不是2个。
因此,困难的部分是找到尽可能不同的类结构路径。这并非总是可能的。如果是这样,则必须首先添加收敛路径的叶子。在示例中:首先插入订单类型。插入新公司后,您首先将现有订单类型加载到上下文中,然后添加公司。现在,将新订单链接到现有订单类型。仅当您可以通过自然键匹配对象(在此示例中:订单类型名称)时,才可以这样做,但是通常这是可能的。
您必须注意不要插入主数据的多个副本。假设前面的示例中的订单类型在所有数据库中都是相同的(尽管它们的主键可能会有所不同!)。源数据库中的订单类型不应重新插入目标数据库中。此外,您必须将源数据中的引用固定到目标数据库中的正确记录(再次通过自然键匹配)。
因此,尽管这不是一件容易的事,但它是可行的,并且工作是在相对较短的时间内完成的。我敢肯定,其他选择(t-SQL,集成服务,BIDS,如果可以的话)将花费更多的时间,或者会带来更多的错误。而且,该区域中的错误的问题在于,它们可能会在以后变得很明显。
后来我发现,我在2)下描述的问题与使用获取源对象有关AsNoTracking
。参见这篇有趣的文章:Entity Framework 6-使用我的getHashCode()。我AsNoTracking
之所以使用它,是因为它性能更好,并且减少了内存消耗。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句