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
, EmployeeProfile
e Skill
:
Primeiro, baixe o projeto de RH:
Segundo, execute o Add-Migration
comando no Package Manager Console (PMC) para criar uma nova migração:
Add-Migration Initial
Terceiro, execute o Update-Database
PMC
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 daDbContext
classe.
Por exemplo, o comando a seguir cria um novo departamento, adiciona-o ao DbSet<Department>
e chama o SaveChanges()
método do HRContext
para inserir um departamento na Departments
tabela:
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 INSERT
instrução simples para inserir um novo departamento na Departments
tabela e retorna o Id inserido.
Se você visualizar a Departments
tabela, 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 correspondente
DbSet
- Terceiro, chame o
SaveChanges()
método deDbContext
para criar as entidades na tabela do banco de dados.
Por exemplo, o seguinte ilustra como inserir múltiplas Department
entidades:
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 MERGE
instruçã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 IT
Linguagem 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 Employee
possui a DepartmentId
propriedade 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 1
Linguagem 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á IT
usando uma SELECT
declaraçã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_0
Linguagem 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 6
Linguagem 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 EmployeeProfile
tabelas 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 Employee
objeto e atribuímos 1 à DepartmentId
propriedade e um novo EmployeeProfile
objeto à Profile
propriedade.
Depois de adicionar o funcionário Employees
DbSet
e chamar o SaveChanges()
método, o EF Core gera e executa os dois comandos SQL:
Primeiro, insira uma nova linha na Employees
tabela e retorne o Id
valor 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 1
Linguagem de código: texto simples ( texto simples )
Segundo, insira uma nova linha na EmployeeProfiles
tabela. O EmployeeProfile
objeto foi EmployeeId
retornado 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 3
Linguagem 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
DepartmentId
6, que é oIT
departamento.- Uma lista de dois
Skill
objetos
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 Employees
tabela e retorne o id usando a INSERT
instruçã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 6
Linguagem de código: CSS ( css )
Segundo, insira várias linhas na Skills
tabela usando a MERGE
instruçã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 Core
Linguagem de código: texto simples ( texto simples )
Terceiro, insira várias linhas na EmployeeSkill
tabela usando a INSERT
instruçã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 2
Linguagem de código: texto simples ( texto simples )
Resumo
- Crie uma nova entidade, adicione-a ao correspondente
DbSet
e chame oSaveChanges()
para inserir uma nova linha na tabela correspondente.