我们有15个数据库,共75个表,平均行数为100万。所有具有相同的架构但不同的数据。我们现在已经满足了客户要求将所有15个数据库整合到一个数据库中的要求。每组数据都由用户登录过滤。
已完成对应用程序的更改以进行过滤。我们现在的任务是将所有数据库合并为一个。
问题是PK和FK是冲突的,因为PK和FK是int类型所以我们将有15个PK ID为1。
一个想法是使用。 net和DBML将记录作为新记录插入到新数据库中,让linq处理PK和FK并使用代码处理重复数据。
还有其他方法吗?
答案 0 :(得分:2)
当记录在所有数据库中没有唯一的主键时,集成数据库从来都不是一项简单的工作。几周前,我构建了一个类似的集成脚本,我决定使用Entity Framework。
首先好消息。使用EF的DbContext
API,插入完整的对象图并使EF处理所有新生成的主键是一个外键非常容易。这很容易的原因是,当一个对象的状态变为Added
时,其所有的粘附对象也变为Added
,并且EF计算出正确的插入顺序。这真是太棒了!它使我在几个小时内构建了复制例程的核心,如果我应该在T-SQL中完成它,那将是许多天。后者也更容易出错。
当然生活 很容易。现在是坏消息:
这需要大量机器资源。当然,我为每个复制步骤使用了一个新的上下文实例,但我仍然必须在具有合适处理器和相当数量的内部存储器的机器上执行该程序。确切的规范无关紧要,信息是:用最大的数据库进行测试,看看你需要什么样的野兽。如果任何机器都无法管理内存消耗,则必须将例程拆分为较小的块,但这需要更多的编程。
更改为Added
的对象图必须发散。我的意思是,从根开始只应该有1-n
个关联。原因是,EF会将所有对象标记为Added
。因此,如果图中某处有一些分支引用同一个对象(因为存在n-1
关联),则这些“新”对象将成倍增加,因为EF不知道它们的身份。这方面的一个例子可能是Company -< Customer
- &lt; Order
&gt; - OrderType
:当只有2种订单类型时,插入一个拥有10个客户的根公司,每个订单10个订单,将创建100个订单类型记录,而不是2个。
所以困难的部分是找到尽可能分散的类结构路径。这并非总是可行的。如果是这样,您将必须首先添加聚合路径的叶子。在示例中:首先插入订单类型。插入新公司时,首先将现有订单类型加载到上下文中,然后添加公司。现在将新订单链接到现有订单类型。只有在您可以通过自然键匹配对象(在此示例中:订单类型名称)时才能执行此操作,但通常可以这样做。
您必须注意不要插入主数据的多个副本。假设前一个示例中的订单类型在所有数据库中都是相同的(尽管它们的主键可能不同!)。源数据库中的订单类型不应重新插入目标数据库中。此外,您必须将源数据中的引用修复为目标数据库中的正确记录(再次通过自然键进行匹配)。
因此虽然这不是微不足道的,但它是可行的,而且工作是在相对较短的时间内完成的。我敢肯定其他替代方案(t-SQL,集成服务,BIDS,如果可行的话)会花费更多时间或者更多的错误。而这个领域的漏洞问题是它们可能会在以后很明显。
我后来发现我在2)中描述的问题与使用AsNoTracking
获取源对象有关。看到这篇有趣的帖子:Entity Framework 6 - use my getHashCode()。我使用AsNoTracking
因为它表现更好而且减少了内存消耗。