在我们的数据库中,我们有这种父 - 子 - 孙关系是多对多关系(两次)。这通过两个交叉/交叉引用表发生。 Parent / Child / Grandschild表具有唯一的varchar功能键。以下是仅显示层次结构中第一步的简化版本:
Parent Junction Child
+----+-------+ +------+------+ +----+-------+
| PK | F_KEY | | PK_1 | PK_2 | | PK | F_KEY |
+----+-------+ +------+------+ +----+-------+
| 1 | AAA | | 1 | 1 | | 1 | BBB |
+----+-------+ +------+------+ +----+-------+
父母/子女/孙子女的记录数量都是数百万。
场合
我们需要处理我们已经给出父子孙子集合的情况,其中一些可能已经存在于数据库中。我们需要插入尚未存在的那些,忽略rest(基于功能键)。
所以当前的实施:
毫不奇怪 - 出现了问题,现在我们在联结表中缺少链接,我们不得不通过脚本修复此问题。
这种实施并不适合我。开发者的争论是表现。原始实施没有执行:
没有表演。我的同事说 - 想一想:你必须进入父母,然后找回身份证。保存孩子,检索身份证,将这些用于第一个联络表等。'
问题
我该如何表演?我的意思是 - 它有效,但不是很容易维护,真的让我误解了。
我有一个想法 - 如果我们使联结表包含如此唯一的功能键:
Parent Junction Child
+----+-------+ +------+------+ +----+-------+
| PK | F_KEY | | PK_1 | PK_2 | | PK | F_KEY |
+----+-------+ +------+------+ +----+-------+
| 1 | AAA | | AAA | BBB | | 1 | BBB |
+----+-------+ +------+------+ +----+-------+
然后我们不必检索插入项目的ID以将它们存储在联结表中。那有意义吗? EF能够从中受益吗?
如果这不起作用 - 我们不会以最佳状态使用EF - 我们不妨考虑使用存储过程或直接查询数据库。您可以完全节省EF的开销,至少可以完全控制我们正在做的事情,而EF不会在幕后为我们提供查询。
对此有何看法?当然,任何其他建议都非常受欢迎。
答案 0 :(得分:1)
对于这种任务,我会创建一个存储过程,接受几个表值参数https://msdn.microsoft.com/en-us/library/bb510489.aspx https://msdn.microsoft.com/en-us/library/bb675163(v=vs.110).aspx,其中包含新Parents
,Children
,{{ 1}},Junctions
,GrandChildren
并在一个事务内执行服务器上的所有合并,而不将任何内容发送回客户端。
在类似的情况下,批量处理行的一堆MERGE
T-SQL语句对我来说效果很好。
合并Junctions
,然后合并Parents
,然后合并Children
个表格。然后在GrandChildren
和Junction
之间Parents
。然后在Children
和Junction
之间Children
。
只要您需要合并的集合大小合理(例如,大约10K行),只需调用一次存储过程就能很好地工作。如果必须合并更多行,请考虑将它们分成较小的批次并多次调用存储过程。