Entity Framework是.NET平台下的一种简单易用的ORM框架,它既便于Domain Model和持久层的OO设计,也提高了代码的可维护性。但在使用中发现,有几类业务场景是EF不太擅长的,比如批量写入大量同类数据,为此本人做了一些对比测试,以供大家参考。

现假设我们需要做一个用户批量导入的功能,需要从某处导入1k~1w个User到SQLServer数据库,本人听说过的常见做法有如下几种:

  1. 使用ADO.NET单条SqlCommand执行1w次(根据常识作为EF的替代其性能还不够格,所以就不做测试了)
  2. 使用StringBuilder拼接SQL语句,将1w条Insert语句拼接成1到若干条SqlCommand执行
  3. 使用EntityFramework的基本功能进行插入
  4. 使用SqlBulkCopy进行批量插入
  5. 使用存储过程,其中的2种分支分别对应上述1、2用例,另外还有1种表参数存储过程。

数据库准备工作:

 1 CREATE DATABASE BulkInsertTest
 2 GO
 3 
 4 USE BulkInsertTest
 5 GO
 6 
 7 CREATE TABLE [dbo].[User](
 8     [Id] [int] IDENTITY(1,1) NOT NULL,
 9     [Name] [nvarchar](50) NOT NULL,
10     [Birthday] [date] NOT NULL,
11     [Gender] [char](1) NOT NULL,
12     [Email] [nvarchar](50) NOT NULL,
13     [Deleted] [bit] NOT NULL,
14  CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
15 (
16     [Id] ASC
17 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
18 ) ON [PRIMARY]
19 
20 GO
21 
22 CREATE PROCEDURE [dbo].[InsertUser] 
23     @Name nvarchar(50)
24            ,@Birthday date
25            ,@Gender char(1)
26            ,@Email nvarchar(50)
27            ,@Deleted bit
28 AS
29 BEGIN
30     INSERT INTO [BulkInsertTest].[dbo].[User]
31            ([Name]
32            ,[Birthday]
33            ,[Gender]
34            ,[Email]
35            ,[Deleted])
36      VALUES
37            (@Name,@Birthday,@Gender,@Email,@Deleted)
38 
39 END
40 
41 /* Create a table type. */
42 CREATE TYPE LocationTableType AS TABLE 
43 ( Name nvarchar(50)
44            ,Birthday date
45            ,Gender char(1)
46            ,Email nvarchar(50)
47            ,Deleted bit );
48 GO
49 
50 /* Create a procedure to receive data for the table-valued parameter. */
51 CREATE PROCEDURE [dbo].[InsertUsers]
52     @Users LocationTableType
53     AS 
54     SET NOCOUNT ON
55     INSERT INTO [dbo].[User]
56            ([Name]
57            ,[Birthday]
58            ,[Gender]
59            ,[Email]
60            ,[Deleted])
61         SELECT *
62         FROM  @Users;
63 
64 GO
View Code

相关文章: