Resumo : neste tutorial, você aprenderá várias maneiras de atualizar dados em tabelas de banco de dados no EF Core.
Configurando um projeto de exemplo
Primeiro, baixe o projeto de exemplo de RH:
Baixe o projeto de amostra do EF Core HR
Segundo, execute o comando Add-Migration no Package Manager Console (PMC) para criar uma nova migração:
Add-Migration Initial
Linguagem de código: C# ( cs )
Terceiro, execute o comando Update-Database no PMC para criar um novo banco de dados e tabelas de RH no SQL Server local:
Update-Database
Linguagem de código: C# ( cs )
Executando uma atualização simples
Começaremos com a Department
entidade:
Vamos começar inserindo um novo departamento na Departments
tabela criando uma nova Department
entidade, adicionando-a ao DbSet<Department>
e chamando o SaveChanges()
método do HRContext
:
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 )
O EF Core irá inserir uma linha na Departments
tabela com id 1.
Para atualizar uma entidade, siga estas etapas:
- Primeiro, obtenha a entidade consultando-a no banco de dados.
- Em segundo lugar, faça alterações na entidade.
- Terceiro, chame o
SaveChanges()
método deDbContext
para propagar as alterações no banco de dados.
Por exemplo, o seguinte altera o nome do Sales
departamento com Id 1
para Sales Force
:
using HR;
using var context = new HRContext();
// get the department by Id
var department = context.Departments.Find(1);
if (department != null)
{
// make changes to the department
department.Name = "Sales Force";
// update the changes
context.SaveChanges();
}
Linguagem de código: C# ( cs )
Observe que HRContext
estende DbContext
e define DbSet
como Departments
com o type DbSet<Department>
.
Como funciona.
Primeiro, encontre o departamento com Id 1 usando o Find()
método:
var department = context.Departments.Find(1);
Linguagem de código: C# ( cs )
O EF Core executa uma SELECT
instrução SQL para localizar o departamento por Id:
-- [Parameters = [@__p_0 = '1' ], CommandType = 'Text', CommandTimeout = '30' ]
SELECT
TOP(1) [d].[Id],
[d].[Name]
FROM
[Departments] AS [d]
WHERE
[d].[Id] = @__p_0
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, altere o nome do departamento para Sales Force
:
department.Name = "Sales Force";
Linguagem de código: C# ( cs )
Terceiro, salve as alterações no banco de dados chamando o Update()
método de HRContext
:
context.SaveChanges();
Linguagem de código: C# ( cs )
O EF Core executa a UPDATE
instrução SQL para atualizar a Departments
tabela:
-- [Parameters=[@p1='1', @p0='Sales Force' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET COCOUNT ON;
UPDATE
[Departments]
SET
[Name] = @p0
OUTPUT 1
WHERE
[Id] = @p1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Se você visualizar a Departments
tabela, verá que o nome foi atualizado com sucesso:
Id Name
----------- --------------------
1 Sales Force
Linguagem de código: texto simples ( texto simples )
Atualizando entidade com ID
Se você souber o ID da entidade, poderá atualizá-lo especificando o ID e os novos valores para as propriedades que deseja alterar. Por exemplo:
using HR;
using var context = new HRContext();
// Update the name of department
// with Id 1 to Sales
var department = new Department()
{
Id = 1,
Name = "Sales",
};
context.Update(department);
context.SaveChanges();
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, crie um novo Department
objeto especificando o Id 1 e o novo valor da Name
propriedade:
var department = new Department()
{
Id = 1,
Name = "Sales",
};
Linguagem de código: C# ( cs )
Segundo, chame o Update()
método de DbContext
para atualizar a entidade:
context.Update(department);
Linguagem de código: C# ( cs )
Terceiro, chame o SaveChanges()
para aplicar as alterações ao banco de dados:
context.SaveChanges();
Linguagem de código: C# ( cs )
Neste exemplo, o EF Core só precisa executar uma UPDATE
instrução:
-- [Parameters=[@p1='1', @p0='Sales' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
UPDATE [Departments] SET [Name] = @p0
OUTPUT 1
WHERE [Id] = @p1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Observe que se o Id for inválido, o EF Core não conseguirá encontrar o registro para atualização. Nesse caso, o EF Core gerará uma exceção como no exemplo a seguir:
using HR;
using var context = new HRContext();
var department = new Department()
{
Id = 10, // Invalid Id
Name = "Sales",
};
context.Update(department);
context.SaveChanges(); // -> Exception
Linguagem de código: C# ( cs )
Atualizando em um relacionamento um-para-muitos
O programa a seguir adiciona um novo funcionário à Employees
mesa e um departamento à Departments
mesa:
using HR;
using var context = new HRContext();
var department = new Department() { Name = "Marketing" };
var employee = new Employee()
{
FirstName = "John",
LastName = "Doe",
Salary = 120_000,
JoinedDate = new DateTime(2023, 5, 1),
Department = department
};
context.Add(employee);
context.SaveChanges();
Linguagem de código: C# ( cs )
O seguinte mostra o funcionário (não todos os campos) na Employees
tabela:
Id FirstName LastName DepartmentId
----------- --------------- --------------- ------------
1 John Doe 2
Linguagem de código: texto simples ( texto simples )
E aqui está o conteúdo da Departments
tabela:
Id Name
----------- ---------------
1 Sales
2 Marketing
Linguagem de código: texto simples ( texto simples )
Para atualizar o departamento do funcionário de Marketing
para Sales
, você pode alterar o DepartmentId
da Employee
entidade e chamar o SaveChanges()
método:
using HR;
using var context = new HRContext();
var employee = context.Employees.Find(1);
if(employee != null)
{
employee.DepartmentId = 2;
context.SaveChanges();
}
Linguagem de código: C# ( cs )
Depois de executar o programa, você verá que o arquivo DepartmentId
está atualizado:
Id FirstName LastName DepartmentId
----------- --------------- --------------- ------------
1 John Doe 2
Linguagem de código: texto simples ( texto simples )
Como alternativa, você pode alterar a Department
propriedade da entidade funcionário para outro departamento e chamar o método SaveChanges()
.
O exemplo a seguir altera o departamento de John Doe
volta para Sales
:
using HR;
using var context = new HRContext();
// find the employee with id 1
var employee = context.Employees.Find(1);
if (employee != null)
{
// find the Sales department
var department = context.Departments
.Where(d => d.Name == "Sales")
.FirstOrDefault();
if (department != null)
{
employee.Department = department;
context.SaveChanges();
}
}
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, encontre o funcionário com id 1:
var employee = context.Employees.Find(1);
Linguagem de código: C# ( cs )
O EF Core executa uma SELECT
instrução para localizar o funcionário por id:
-- [Parameters=[@__p_0='1'], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [e].[Id], [e].[DepartmentId], [e].[FirstName], [e].[JoinedDate], [e].[LastName], [e].[Salary]
FROM [Employees] AS [e]
WHERE [e].[Id] = @__p_0
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, encontre o departamento pelo nome com o valor "Sales"
e obtenha o primeiro:
var department = context.Departments
.Where(d => d.Name == "Sales")
.FirstOrDefault();
Linguagem de código: C# ( cs )
-- [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [d].[Id], [d].[Name]
FROM [Departments] AS [d]
WHERE [d].[Name] = N'Sales'
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Terceiro, atualize o departamento do funcionário e ligue SaveChanges()
para aplicar a alteração ao banco de dados:
employee.Department = department;
context.SaveChanges();
Linguagem de código: C# ( cs )
O EF Core executará a seguinte UPDATE
instrução:
-- [Parameters=[@p1='1', @p0='1'], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
UPDATE [Employees] SET [DepartmentId] = @p0
OUTPUT 1
WHERE [Id] = @p1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Atualizando em um relacionamento um-para-um
O exemplo a seguir mostra como adicionar um perfil a um funcionário:
using HR;
using var context = new HRContext();
// find the employee with id 1
var employee = context.Employees.Find(1);
if (employee != null)
{
// create a profile for the employee
employee.Profile = new EmployeeProfile()
{
Phone = "(408)-111-2222",
Email = "[email protected]"
};
context.SaveChanges();
}
Linguagem de código: C# ( cs )
O EF Core insere uma linha na EmployeeProfiles
tabela e define o valor de EmployeeId
como o valor do Id do funcionário:
Id Phone Email EmployeeId
----------- -------------------- -------------------- -----------
1 (408)-111-2222 [email protected] 1
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Para atualizar o telefone do funcionário, você pode consultar o perfil do funcionário, modificar o telefone e ligar SaveChanges()
da seguinte forma:
using HR;
using Microsoft.EntityFrameworkCore;
using var context = new HRContext();
// find the employee with id 1
var employee = context.Employees
.Include(e => e.Profile)
.Where(e => e.Id == 1)
.FirstOrDefault();
if (employee is not null && employee.Profile is not null)
{
employee.Profile.Phone = "(408)-555-5555";
context.SaveChanges();
}
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, encontre o funcionário, incluindo o perfil, com id 1:
var employee = context.Employees
.Include(e => e.Profile)
.Where(e => e.Id == 1)
.FirstOrDefault();
Linguagem de código: C# ( cs )
-- [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [e].[Id], [e].[DepartmentId], [e].[FirstName], [e].[JoinedDate], [e].[LastName], [e].[Salary], [e0].[Id], [e0].[Email], [e0].[EmployeeId], [e0].[Phone]
FROM [Employees] AS [e]
LEFT JOIN [EmployeeProfiles] AS [e0] ON [e].[Id] = [e0].[EmployeeId]
WHERE [e].[Id] = 1
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, modifique o telefone e atualize o banco de dados:
employee.Profile.Phone = "(408)-555-5555";
context.SaveChanges();
Linguagem de código: C# ( cs )
-- [Parameters=[@p1='1', @p0='(408)-555-5555' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
UPDATE [EmployeeProfiles] SET [Phone] = @p0
OUTPUT 1
WHERE [Id] = @p1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Se você visualizar a EmployeeProfiles
tabela, verá que o telefone do funcionário está atualizado:
Id Phone Email EmployeeId
----------- -------------------- -------------------- -----------
1 (408)-555-5555 [email protected] 1
Linguagem de código: texto simples ( texto simples )
Atualizando em um relacionamento muitos para muitos
A seguir, adicione duas habilidades ao funcionário com id 1:
using HR;
using var context = new HRContext();
var employee = context.Employees.Find(1);
if (employee is not null)
{
var skills = new List<Skill>()
{
new() { Title = "Sales Planning" },
new() { Title = "Sales Strategy" }
};
foreach (var skill in skills)
{
employee.Skills.Add(skill);
}
context.SaveChanges();
}
Linguagem de código: C# ( cs )
O EF Core irá inserir duas novas linhas na tabela Skills:
Id Title
----------- --------------------
1 Sales Planning
2 Sales Strategy
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
E atribua-o ao funcionário com Id 1 inserindo duas linhas na EmployeeSkill
tabela:
EmployeesId SkillsId
----------- -----------
1 1
1 2
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Veja a seguir como remover o "Sales Strategy"
ID do funcionário 1 e adicionar uma nova habilidade "Market Trend Analysis"
ao funcionário:
using HR;
using static System.Console;
using Microsoft.EntityFrameworkCore;
using var context = new HRContext();
// find employee with skills
var employee = context.Employees
.Include(e => e.Skills)
.Where(e => e.Id == 1)
.FirstOrDefault();
if (employee is not null && employee.Skills.Count > 0)
{
// remove the "Sales Strategy" skill
var skill = employee.Skills.Find(s => s.Title == "Sales Strategy");
if(skill is not null)
{
employee.Skills.Remove(skill);
}
// add "Market Trend Analysis" skill
employee.Skills.Add(new Skill() { Title = "Market Trend Analysis" });
}
context.SaveChanges();
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, encontre o funcionário com id 1 e também adquira as habilidades:
var employee = context.Employees
.Include(e => e.Skills)
.Where(e => e.Id == 1)
.FirstOrDefault();
Linguagem de código: C# ( cs )
-- [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Id], [t].[DepartmentId], [t].[FirstName], [t].[JoinedDate], [t].[LastName], [t].[Salary], [t0].[EmployeesId], [t0].[SkillsId], [t0].[Id], [t0].[Title]
FROM (
SELECT TOP(1) [e].[Id], [e].[DepartmentId], [e].[FirstName], [e].[JoinedDate], [e].[LastName], [e].[Salary]
FROM [Employees] AS [e]
WHERE [e].[Id] = 1
) AS [t]
LEFT JOIN (
SELECT [e0].[EmployeesId], [e0].[SkillsId], [s].[Id], [s].[Title]
FROM [EmployeeSkill] AS [e0]
INNER JOIN [Skills] AS [s] ON [e0].[SkillsId] = [s].[Id]
) AS [t0] ON [t].[Id] = [t0].[EmployeesId]
ORDER BY [t].[Id], [t0].[EmployeesId], [t0].[SkillsId]
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, desassocie a habilidade do funcionário:
var skill = employee.Skills.Find(s => s.Title == "Sales Strategy");
if(skill is not null)
{
employee.Skills.Remove(skill);
}
Linguagem de código: C# ( cs )
-- [Parameters=[@p0='1', @p1='2', @p2='Market Trend Analysis' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [EmployeeSkill]
OUTPUT 1
WHERE [EmployeesId] = @p0 AND [SkillsId] = @p1;
INSERT INTO [Skills] ([Title])
OUTPUT INSERTED.[Id]
VALUES (@p2);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Tabela de habilidades:
Id Title
----------- -------------------------
1 Sales Planning
2 Sales Strategy
3 Market Trend Analysis
Linguagem de código: texto simples ( texto simples )
Terceiro, insira uma nova habilidade na Skills
tabela e associe a nova habilidade ao funcionário:
employee.Skills.Add(new Skill() { Title = "Market Trend Analysis" });
Linguagem de código: C# ( cs )
INSERT INTO [Skills] ([Title])
OUTPUT INSERTED.[Id]
VALUES (@p2);
-- [Parameters=[@p3='1', @p4='3'], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [EmployeeSkill] ([EmployeesId], [SkillsId])
VALUES (@p3, @p4);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
EmployeeSkill
mesa:
EmployeesId SkillsId
----------- -----------
1 1
1 3
Linguagem de código: texto simples ( texto simples )
Resumo
- Para atualizar uma entidade, obtenha sua instância do banco de dados, modifique-a e chame o
SaveChanges()
método para atualizar.