Inserção do núcleo EF

Resumo : neste tutorial, você aprenderá como usar o SaveChanges()método EF Core para inserir linhas em tabelas.

Configurando um projeto EF Core

Usaremos o seguinte modelo de dados que inclui Department, Employee, EmployeeProfilee Skill:

Modelo de dados principais do EF

Primeiro, baixe o projeto de RH:

Baixe o projeto de RH

Segundo, execute o Add-Migrationcomando no Package Manager Console (PMC) para criar uma nova migração:

Add-Migration Initial

Terceiro, execute o Update-DatabasePMC para criar um novo banco de dados e tabelas:

Update-Database

Inserindo uma única linha

Para inserir uma nova linha em uma tabela, siga estas etapas:

  • Primeiro, crie uma nova entidade.
  • Em segundo lugar, adicione-o ao arquivo DbSet.
  • Terceiro, chame o SaveChanges()método da DbContextclasse.

Por exemplo, o comando a seguir cria um novo departamento, adiciona-o ao DbSet<Department>e chama o SaveChanges()método do HRContextpara inserir um departamento na Departmentstabela:

using HR;

using var context = new HRContext();
var department = new Department() { Name = "Sales" };
context.Departments.Add(department);
context.SaveChanges();Linguagem de código:  C#  ( cs )

Ao executar o programa, você verá que o EF Core gera o seguinte comando SQL:

-- [Parameters=[@p0='Sales' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Departments] ([Name])
OUTPUT INSERTED.[Id]
VALUES (@p0);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )

Neste exemplo, o EF Core usa uma INSERTinstrução simples para inserir um novo departamento na Departmentstabela e retorna o Id inserido.

Se você visualizar a Departmentstabela, verá uma linha inserida:

Id          Name
----------- ----------
1           Sales
Linguagem de código:  texto simples  ( texto simples )

Inserindo múltiplas linhas

Para inserir várias linhas em uma tabela:

  • Primeiro, crie várias entidades
  • Segundo, adicione as entidades ao correspondenteDbSet
  • Terceiro, chame o SaveChanges()método de DbContextpara criar as entidades na tabela do banco de dados.

Por exemplo, o seguinte ilustra como inserir múltiplas Departmententidades:

using HR;

using var context = new HRContext();

var deparments = new List<Department>()
{
    new Department(){ Name = "Marketing"},
    new Department(){ Name = "Logistics"},
    new Department(){ Name = "HR"},
    new Department(){ Name = "General Administration"},
    new Department(){ Name = "IT"},
};

foreach (var department in deparments)
{
    context.Departments.Add(department);
}

context.SaveChanges();Linguagem de código:  C#  ( cs )

Nos bastidores, o EF Core gera uma MERGEinstrução para inserir várias linhas em uma tabela, conforme mostrado no log:

-- [Parameters=[@p0='Marketing' (Nullable = false) (Size = 4000), @p1='Logistics' (Nullable = false) (Size = 4000), @p2='HR' (Nullable = false) (Size = 4000), @p3='General Administration' (Nullable = false) (Size = 4000), @p4='IT' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
MERGE [Departments] USING (
VALUES (@p0, 0),
(@p1, 1),
(@p2, 2),
(@p3, 3),
(@p4, 4)) AS i ([Name], _Position) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([Name])
VALUES (i.[Name])
OUTPUT INSERTED.[Id], i._Position;Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          Name
----------- --------------------------
1           Sales
2           Marketing
3           Logistics
4           HR
5           General Administration
6           ITLinguagem de código:  texto simples  ( texto simples )

Insira uma entidade que tenha um relacionamento um-para-muitos

O seguinte cria um funcionário com ID de departamento 1. Como Employeepossui a DepartmentIdpropriedade de chave estrangeira, você precisa atribuir um valor válido a ele:

using HR;


using var context = new HRContext();

var employee = new Employee()
{
    FirstName = "John",
    LastName = "Doe",
    Salary = 120000,
    JoinedDate = new DateTime(2023,01,05),
    DepartmentId = 1
};

context.Employees.Add(employee);

context.SaveChanges();Linguagem de código:  C#  ( cs )

Se você executar o programa, o EF Core irá gerar o seguinte SQL e executá-lo para inserir uma nova linha na tabela Employees:

 -- [Parameters=[@p0='1', @p1='John' (Nullable = false) (Size = 4000), @p2='2023-01-05T00:00:00.0000000', @p3='Doe' (Nullable = false) (Size = 4000), @p4='120000' (Precision = 18) (Scale = 2)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Employees] ([DepartmentId], [FirstName], [JoinedDate], [LastName], [Salary])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          FirstName  LastName   Salary                         JoinedDate                  DepartmentId
----------- ---------- ---------- ------------------------------ --------------------------- ------------
1           John       Doe        120000.00                      2023-01-05 00:00:00.0000000 1Linguagem de código:  texto simples  ( texto simples )

O exemplo a seguir localiza o departamento de TI e cria um funcionário que pertence a esse departamento:

using HR;


using var context = new HRContext();

// find the IT department
var departmentName = "IT";

var department = context.Departments
                    .Where(d => d.Name == departmentName)
                    .FirstOrDefault();

if (department == null)
{
    Console.WriteLine($"Department {departmentName} not found.");
    return;
}

// create a new employee
var employee = new Employee()
{
    FirstName = "Jane",
    LastName = "Doe",
    Salary = 95000,
    JoinedDate = new DateTime(2023, 1, 5),
    Department = department,
};

context.Employees.Add(employee);
context.SaveChanges();Linguagem de código:  C#  ( cs )

Neste exemplo, o EF Core executa duas consultas:

Primeiro, encontre o departamento cujo nome está ITusando uma SELECTdeclaração:

-- [Parameters=[@__departmentName_0='IT' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [d].[Id], [d].[Name]
FROM [Departments] AS [d]
WHERE [d].[Name] = @__departmentName_0Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )

Segundo, insira uma nova linha na tabela Funcionários:

-- [Parameters=[@p0='6', @p1='Jane' (Nullable = false) (Size = 4000), @p2='2023-01-05T00:00:00.0000000', @p3='Doe' (Nullable = false) (Size = 4000), @p4='95000' (Precision = 18) (Scale = 2)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Employees] ([DepartmentId], [FirstName], [JoinedDate], [LastName], [Salary])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          FirstName  LastName   Salary                         JoinedDate                  DepartmentId
----------- ---------- ---------- ------------------------------ --------------------------- ------------
1           John       Doe        120000.00                      2023-01-05 00:00:00.0000000 1
2           Jane       Doe        95000.00                       2023-01-05 00:00:00.0000000 6Linguagem de código:  texto simples  ( texto simples )

Insira uma entidade que tenha um relacionamento um-para-um

O exemplo a seguir ilustra como inserir um funcionário com perfil nas EmployeeProfiletabelas Funcionários e:

using HR;

var employee = new Employee()
{
    FirstName = "Bob",
    LastName = "Climo",
    JoinedDate = new DateTime(2023, 1, 5),
    Salary=90000,
    DepartmentId = 1,
    Profile = new EmployeeProfile()
    {
        Phone = "(408)-123-456",
        Email = "[email protected]"
    },

};

using var context = new HRContext();
context.Employees.Add(employee);
context.SaveChanges();Linguagem de código:  C#  ( cs )

Neste exemplo, criamos um novo Employeeobjeto e atribuímos 1 à DepartmentIdpropriedade e um novo EmployeeProfileobjeto à Profilepropriedade.

Depois de adicionar o funcionário Employees DbSete chamar o SaveChanges()método, o EF Core gera e executa os dois comandos SQL:

Primeiro, insira uma nova linha na Employeestabela e retorne o Idvalor da linha:

-- [Parameters=[@p0='1', @p1='Bob' (Nullable = false) (Size = 4000), @p2='2023-01-05T00:00:00.0000000', @p3='Climo' (Nullable = false) (Size = 4000), @p4='900000' (Precision = 18) (Scale = 2)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Employees] ([DepartmentId], [FirstName], [JoinedDate], [LastName], [Salary])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          FirstName  LastName   Salary                         JoinedDate                  DepartmentId
----------- ---------- ---------- ------------------------------ --------------------------- ------------
1           John       Doe        120000.00                      2023-01-05 00:00:00.0000000 1
2           Jane       Doe        95000.00                       2023-01-05 00:00:00.0000000 6
3           Bob        Climo      90000.00                      2023-01-05 00:00:00.0000000 1Linguagem de código:  texto simples  ( texto simples )

Segundo, insira uma nova linha na EmployeeProfilestabela. O EmployeeProfileobjeto foi EmployeeIdretornado pela primeira consulta:

-- [Parameters=[@p5='[email protected]' (Nullable = false) (Size = 4000), @p6='3' (Nullable = true), @p7='(408)-123-456' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [EmployeeProfiles] ([Email], [EmployeeId], [Phone])
OUTPUT INSERTED.[Id]
VALUES (@p5, @p6, @p7);Linguagem de código:  C#  ( cs )
Id          Phone           Email           EmployeeId
----------- --------------- --------------- -----------
1           (408)-123-456   bob@example.com 3Linguagem de código:  CSS  ( css )

Insira uma entidade que tenha um relacionamento muitos para muitos

O exemplo a seguir ilustra como criar um novo funcionário com:

  • FirstName, LastName, JoinedDate,Salary
  • DepartmentId6, que é o ITdepartamento.
  • Uma lista de dois Skillobjetos
using HR;

var employee = new Employee()
{
    FirstName = "Alice",
    LastName = "Smith",
    JoinedDate = new DateTime(2023, 1, 5),
    Salary = 70000,
    DepartmentId = 6,  // IT department
    Skills = new List<Skill>()
    {
        new (){ Title="C# Programming" },
        new (){ Title="ASP.NET Core" }
    }

};

using var context = new HRContext();
context.Employees.Add(employee);
context.SaveChanges();Linguagem de código:  C#  ( cs )

Depois de executar o programa, o EF Core executa três instruções SQL.

Primeiro, insira uma nova linha na Employeestabela e retorne o id usando a INSERTinstrução:

-- [Parameters=[@p0='6', @p1='Alice' (Nullable = false) (Size = 4000), @p2='2023-01-05T00:00:00.0000000', @p3='Smith' (Nullable = false) (Size = 4000), @p4='70000' (Precision = 18) (Scale = 2), @p5='C# Programming' (Nullable = false) (Size = 4000), @p6='ASP.NET Core' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Employees] ([DepartmentId], [FirstName], [JoinedDate], [LastName], [Salary])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          FirstName  LastName   Salary                         JoinedDate                  DepartmentId
----------- ---------- ---------- ------------------------------ --------------------------- ------------
1           John       Doe        120000.00                      2023-01-05 00:00:00.0000000 1
2           Jane       Doe        95000.00                       2023-01-05 00:00:00.0000000 6
3           Bob        Climio     90000.00                       2023-01-05 00:00:00.0000000 1
4           Alice      Smith      70000.00                       2023-01-05 00:00:00.0000000 6Linguagem de código:  CSS  ( css )

Segundo, insira várias linhas na Skillstabela usando a MERGEinstrução e retorne os IDs inseridos:


MERGE [Skills] USING (
VALUES (@p5, 0),
(@p6, 1)) AS i ([Title], _Position) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([Title])
VALUES (i.[Title])
OUTPUT INSERTED.[Id], i._Position;Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Id          Title
----------- -------------------------
1           C# Programming
2           ASP.NET CoreLinguagem de código:  texto simples  ( texto simples )

Terceiro, insira várias linhas na EmployeeSkilltabela usando a INSERTinstrução:

--  [Parameters=[@p7='4', @p8='1', @p9='4', @p10='2'], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [EmployeeSkill] ([EmployeesId], [SkillsId])
VALUES (@p7, @p8),
(@p9, @p10);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
EmployeesId SkillsId
----------- -----------
4           1
4           2Linguagem de código:  texto simples  ( texto simples )

Resumo

  • Crie uma nova entidade, adicione-a ao correspondente DbSete chame o SaveChanges()para inserir uma nova linha na tabela correspondente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *