【问题标题】:How to use Dapper for bulk insert with foreign keys?如何使用 Dapper 进行带有外键的批量插入?
【发布时间】:2016-02-19 02:47:53
【问题描述】:

我有一个像这样的 C# 数据结构:

public class Invoice
{
    public string InvoiceNumber {get;set;}
    public List<SalesPerson> SalesPersons {get;set;}
}

public class SalesPerson
{
    public string Name {get;set;}
}

这对应于两个表:Invoice 和 SalesPerson。一张发票可以有任意数量的这些关联。

现在,我正在创建一个批量上传工具,接收一个 CSV 文件并创建一个发票集合(每个发票都有一些关联的 SalesPerson 记录)。

我可以用 Dapper 想一个简单的方法:遍历每个 Invoice,插入它,获取身份(一个整数 ID 列),遍历该发票中的每个 SalesPerson,使用我作为外国人获得的身份插入钥匙。但这似乎会给我的 SQL 服务器带来很多不必要的流量。

我知道“批量”插入可以多次执行插入命令,但我不知道在这种情况下会如何工作,因为我当时不知道外键'正在构造参数。

有没有比我上面概述的幼稚方式更好的插入方式? Dapper 是不是这个错误的工具? (我正在使用 SQL Server;如果有一些 tSQL 命令可以帮助我,我不知道)

【问题讨论】:

  • 看看 marc_s 的回答——这取决于你的数据库,而不是 Dapper。
  • 另一种方法是创建一个规范化表,其中包含 both 实体的列。将行作为批处理插入,然后从那里拆分到它们的目标表中。

标签: c# sql-server bulkinsert dapper


【解决方案1】:

Dapper 旨在成为一个通用的 ADO.NET 工具,对特定于提供商的功能提供一些最低限度的支持。批量插入 不是通用 API - 不是通用批量插入类。如果您使用的是 SQL Server,SqlBulkCopy 将是显而易见的选择。将其与基于类的对象模型结合使用时,FastMember 是一个很好的盟友。例如:

var data = ... // some List<Foo> where Foo has Id, Name and Description
using(var bcp = new SqlBulkCopy(connection)) // SqlBulkCopy
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) // FastMember
{
    // these bits are part of the SqlBulkCopy API; WriteToServer accepts *either* a
    // DataTable or an IDataReader; we're providing the latter via FastMember
    bcp.DestinationTableName = "SomeTable";
    bcp.WriteToServer(reader);
}

dapper 而言, 支持表值参数,但这需要您在 SQL Server 中创建命名类型。但如果你想考虑这条路线,请参阅Does Dapper support SQL 2008 Table-Valued Parameters?

table-valued-parameters 选项的一个优点是,您可以将 INSERT 语句与 OUTPUT clause 结合起来,一次性获取所有 ID。相比之下:使用SqlBulkCopy,您需要在插入之后查询数据(本质上:SqlBulkCopy 操作没有返回任何内容)。

【讨论】:

  • 这是有用的信息,我当然可以使用除 dapper 之外的东西,但我在概念上遗漏了一些东西——我必须插入两个表,第二个表需要来自第一个表(由 SQL Server 为我自动生成)。我该如何协调呢?
  • @mgroves 在这种情况下,您可能想查看表值参数和OUTPUT 子句用法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
相关资源
最近更新 更多