我正在尝试使用dapper在表上处理一组ID(不是主键 - 这是一个标识int列)的upsert。这不需要是一个精巧的功能,只是包括在有帮助的情况下。
我想知道是否可以(通过直接SQL或使用dapper函数)在ID集合(特别是IEnumerable
of int)上运行upsert。
我真的只需要一个简单的例子让我开始,所以一个例子是:
我有三个类型为Foo的对象:
我有一个名为Bar的表,具有相同的列名(仅存在1033333):
表 Foo
列 ID | ExternalID | DescriptorString |其他的东西
值 [1] | [1033333] | [“我是描述性字符串555”] | [“这是其他一些东西555”]
好吧,既然你说这不需要基于dapper ;-),我会说最快和最干净的方法来获取这些数据是使用SQL Server中引入的表值参数(TVP)您需要创建一个用户定义的表类型(一次)来定义结构,然后您可以在即席查询中使用它或传递给存储过程。但是这样您不需要导出到导入文件,也不需要将其转换为XML只是为了将其转换回表。
我没有复制/粘贴一个大的代码块,而是注意到下面的三个链接,我已经发布了代码来执行此操作(所有这些都在SO上)。前两个链接是完成此代码的完整代码(SQL和C#)(第二个链接最类似于您要执行的操作)。每个主题都略有不同(表明使用TVP的灵活性)。第三个是另一个变体,但不是完整的代码,因为它只是显示前两个中的一个的差异,以适应该特定情况。但在所有3种情况下, 数据都从应用程序流式传输到SQL Server 。没有创建任何其他集合或外部文件;您使用当前拥有的内容,只需要一次复制单行的值即可发送。在SQL Server端,它都是作为填充的表变量而来的。这比获取内存中的数据,将其转换为文件(占用时间和磁盘空间)或XML(占用CPU和内存)或DataTable(适用于SqlBulkCopy
;占用CPU和内存)或其他内容要高效得多,只依赖于文件系统等外部因素(文件需要清理,对吗?)还是需要解析XML。
现在, MERGE
命令存在一些问题(请参阅对SQL Server的MERGE语句使用警告 ),这可能是避免使用它的原因。所以,我已经发布了多年来一直使用的“upsert”代码,以回答DBA.StackExchange: