c# - EntityFrameworkCore 不批处理插入

标签 c# entity-framework-core-2.2

在学习 EntityFrameworkCore 上的其中一门 PluralSight 类(class)时,我从视频中看到了不同的结果。即,当调用 DbSet<...>.AddRange(item 1, item2) , 然后 DbSet<...>.SaveChanges ,我看到了两个简单的 INSERT 语句,而不是一个复杂的 INSERT 语句。

要在 Visual Studio 2017 中重新创建它:

  1. 使用 C# 4.7.2 创建一个新的 .NET Framework 控制台应用程序。将其命名为SomeUI
  2. 在程序包管理器控制台中运行以下命令
    • Install-Package Microsoft.Extensions.Logging.Console SomeUI -Version 2.2.0
    • Install-Package Microsoft.EntityFrameworkCore.SqlServer SomeUI -Version 2.2.6
    • Install-Package Microsoft.EntityFrameworkCore.Tools SomeUI -Version 2.2.6
  3. 将下面的代码粘贴为 Program.cs。
  4. 在程序包管理器控制台中运行以下命令
    • Add-Migration initial
    • Update-Database

程序.cs:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;

namespace SomeUI
{
    public class Samurai
    {
        public String Name { get; set; }
        public int Id { get; set; }
    }

    public class SamuraiContext : DbContext
    {
        public DbSet<Samurai> Samurais { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseLoggerFactory(new ServiceCollection()
                    .AddLogging(builder => builder
                        .AddConsole()
                        .AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Information))
                    .BuildServiceProvider()
                    .GetService<ILoggerFactory>())
                .UseSqlServer("Server = (localdb)\\mssqllocaldb; Database = SamuraiAppData; Trusted_Connection = True; ");
        }

        static void Main(string[] args)
        {
            using (var context = new SamuraiContext())
            {
                context.Samurais.AddRange(new Samurai { Name = "Jack" }, new Samurai { Name = "Jill" });
                context.SaveChanges();
            }
        }
    }
}

我所看到的:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 2.2.6-servicing-10079 initialized 'SamuraiContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (18ms) [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      INSERT INTO [Samurais] ([Name])
      VALUES (@p0);
      SELECT [Id]
      FROM [Samurais]
      WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      INSERT INTO [Samurais] ([Name])
      VALUES (@p0);
      SELECT [Id]
      FROM [Samurais]
      WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();

我应该看到的:

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (18ms) [Parameters=[@p0='?' (Size = 4000)], @p1='?' (Size=4000)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      DECLARE @inserted0 TABLE ([Id] int, [_Position] [int]);
      MERGE [Samurais] USING (
      VALUES (@p0, 0),
      (@p1, 1)) AS i ([Name], _Position) ON 1=0
      WHEN NOT MATCHED THEN
      INSERT ([Name])
      VALUES (i.[Name])
      OUTPUT INSERTED.[Id], i._Position
      INTO @inserted0;

      SELECT [t].[Id] FROM [Samurais] t
      INNER JOIN @inserted0 i ON ([t].[Id] = [i].[Id])
      ORDER BY [i].[_Position];

知道可能出了什么问题吗?提前感谢任何可以帮助我在这里获得一些见解的人。

最佳答案

好吧,这是我最喜欢的答案,就像,永远。

您根本没有足够的武士。尝试七:

  context.Samurais.AddRange(
         new Samurai { Name = "Kambei Shimada" }, 
         new Samurai { Name = "Gorōbei Katayama" },
         new Samurai { Name = "Shichirōji" },
         new Samurai { Name = "Kyūzō" },
         new Samurai { Name = "Heihachi Hayashida" },
         new Samurai { Name = "Katsushirō Okamoto" },
         new Samurai { Name = "Kikuchiyo" }
         );

你会看到命令批处理开始:

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (210ms) [Parameters=[@p0='?' (Size = 4000), @p1='?' (Size = 4000), @p2='?' (Size = 4000), @p3='?' (Size = 4000), @p4='?' (Size = 4000), @p5='?' (Size = 4000), @p6='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      DECLARE @inserted0 TABLE ([Id] int, [_Position] [int]);
      MERGE [Samurais] USING (
      VALUES (@p0, 0),
      (@p1, 1),
      (@p2, 2),
      (@p3, 3),
      (@p4, 4),
      (@p5, 5),
      (@p6, 6)) AS i ([Name], _Position) ON 1=0
      WHEN NOT MATCHED THEN
      INSERT ([Name])
      VALUES (i.[Name])
      OUTPUT INSERTED.[Id], i._Position
      INTO @inserted0;

      SELECT [t].[Id] FROM [Samurais] t
      INNER JOIN @inserted0 i ON ([t].[Id] = [i].[Id])
      ORDER BY [i].[_Position];

您可以在 SqlServerDbContextOptionsBuilder 上配置最小或最大批量大小在 DbContext 的 OnConfiguring 方法中。

关于c# - EntityFrameworkCore 不批处理插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57027814/

相关文章:

c# - 如何从数据表中删除一行?

c# - 使用 MySql.Data.EntityFrameworkCore 包进行 TINYINT 或 BIT 类型映射时遇到问题

c# - System.InvalidOperationException : Variable '' of type '' referenced from scope '' , 但未定义

c# - Entity Framework 中的 ANY 和 ALL 在本地进行评估

c# - ServiceBusTrigger 中的连接是什么?

c# - 如何将 DateTimePicker 设置为只读?

c# - 如何获取数组字段的 FieldInfo?

mariadb - Entity Framework Core + MariaDB - 导航属性为空

c# - EntityFrameworkCore SQLite 内存数据库表未创建