具有子对象的对象的批量插入的性能

时间:2013-07-14 16:17:15

标签: c# sql-server database c#-4.0

我目前正在努力奋斗。

环境: 我正在使用MSSQL Server 2008 R2在C#4.0中改进应用程序。 我没有使用任何类型的ORM。

设计/型号:(虚构)我有一个对话,一条消息和一个附件。对话有多条消息,每条消息可以有多个附件。那边很容易1 .. N连接。

问题:我想在我的数据库中存储一个新对话,包括新的对话消息和新附件。我现在的情况是,我通过保存对话来自上而下。检索该id,将该id设置为消息对象并存储消息(每次执行单独的db调用时)。对于所有附件,同样的故事,我需要先存储消息,然后才能存储这些附件。

我调查或考虑过我的解决方案

  • 目前,我通过存储过程执行这些单独的自上而下的保存机制。

  • SqlBulkCopy:真的很快。我想到了,存储所有对话,获取ID,存储所有消息,获取其ID等等......但问题在这里,我需要做一个查询,例如“给我所有20个最后创建的记录他们的ID”。可行,但是这个应用程序是多线程的,这可能是因为在那一刻其他线程会插入新行或者更糟,删除。

  • 创建存储过程一个疯狂的存储过程,我在其中发送数据集对象(这是更自由的头脑风暴)。

  • 手动生成一个巨大的sql命令,用于存储对话,获取生成的id,并将其用于子对象。喜欢(伪SQL):

    INSERT对话

    currentConversationId = @Identity

    使用conversationId = currentConversationId

  • 插入消息

目标 有人有更好的建议或选择。请避免建议我去ORM,因为我正在处理遗留项目。我想尽可能多地保存数据库电话。

2 个答案:

答案 0 :(得分:2)

使用table-values参数发送多行以在一次调用中插入。您可以使用OUTPUT INSERTED.ID子句检索已创建的ID。使用MERGE语句时,您不仅可以检索ID,还可以检索TVP中的原始值。这对于将ID与TVP行匹配很有用。这可能看起来像这样:

OUTPUT @tvp.SomeID, INSERTED.ID

答案 1 :(得分:1)

  1. 使用表锁执行SqlBulkCopy,以便其他线程不会弄乱您的数据
  2. 在code =>中生成查询我知道有很多项目可以做到这一点,这对批量插入来说似乎是可以接受的......
  3. usr的回答,使用TVP并将ID与自定义生成的数字相关联
  4. 切换到您的ID的GUID(DBA会因此而杀死您:-P)
  5. 祝你好运!