Posts Tagged - entityframeworkcore

EF Core multithreading

I’ve had issues with EF Core when operating with multiple threads and with multiple calls at the same time.

The most important things to check are:

  1. The DbContext is not being shared between calls or threads
  2. All classes which have the context inyected must be scoped (not singleton)
  3. If working with async methods, you need to await calls

I have the following service

public class PersonService(AppDbContext _context)
{
	public async Task<Person> GetPerson(string id)
	{
		return await context.Persons.Find(id);
	}
}

which I may configure as follows

// if I inject it as singleton, this would cause exceptions on multiple calls
services.AddSingleton<IPersonService, PersonService>

// we have to inject it as scoped so it creates a context new for each call
services.AddScoped<IPersonService, PersonService>

Read More

EF Core Global Filters

(TODO: add link -> working code inside this project)

Let’s set a case where we have the following User class where we want to soft delete it, as we want to keep deleted records.

public class User
{
	public int Id { get; set; }
	public string Name { get; set; }
	public bool Active { get; set; }
}

In many cases we don’t care about “deleted” records so most times we will filter out deleted records like this

// DON'T DO THIS
public async Task<List<User>> GetUsers()
{
	return await _context.Users.Where(user => user.Active).ToList();
}

Instead of always doing this, which is too verbose, we may use Global Query Filters. This way we apply the filter globally.

public class ApDbContext : DbContext
{
	// ... more code
	
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.Entity<User>().HasQueryFilter(user => user.Active);
	}
}

From now on, everytime we need to retrieve something from the User table, it will automatically filter out the deleted records.

Read More

Teoria Entity Framework Core

En el Program tenemos código que depende del nugget y la implementación de la base de datos que vamos a integrar.
Este usa una cadena del appsettings.json para conectar a la BBDD

"server=localhost;database=postgres;uid=postgres;password=thisisSomepassword"

Para crear una nueva entidad en la base de datos:

  • Creamos el Model pertinente (por ej.) Coche
  • Lo añadimos al ApplicationDbContext como un DbSet<Coche>
  • Añadimos una migration add-migration addedCoche
  • Ejecutamos update-database

Migration

Mecanismo para aplicar cambios en el modelo de datos de la aplicacion a la BBDD de manera incremental y versionable. Cada migracion contiene los pasos necesarios para llevar a cabo las modificaciones en la BBDD como agregar nuevas tablas, cambiar columnas existentes o eliminar indices.

Esto permite tener:

  • Despliegues consistentes: aplica mismos cambios en diferentes entornos.
  • Control de versiones
  • Evolucionar la BBDD

Read More

Entity Framework Core Scaffolding

Go to Tools > Nuget Package Manager > Package Manager Console

Adapt and paste the following code. This includes:

  • db’s connection string
  • name for the context it’s going to create
  • Where it pastes the data classes to
Scaffold-DBContext "Host=host_here;Database=database_name;Username=username_here;Password=pwd_here" Npgsql.EntityFrameworkCore.PostgreSQL -DataAnnotations -Context ContextNameHereDbContext -ContextDir Data -o Models/DB -force -NoOnConfiguring -verbose

This creates:

  • DbContext.cs class
  • all Model/Data classes

Remember to modify Startup.cs to set the service classes as AddTransient for the services which use this DbContext

services.AddTransient<SomethingService, SomethingService>(); 

Add into the service, the context you’ve just created and set it at the constructor.

private readonly ApplicationDbContext _context;

Read More

EFCore consultas solo lectura - gran volumen entidades

Cuando se van a realizar consultas de solo lectura, las cuales NO se van a usar para actualizar en la base de datos, se puede llamar al método .AsNoTracking() para mejorar la performance.
Es recomendable utilizarla para manejar grandes volumenes de entidades.

Las entidades de las queries donde se use .AsNoTracking() no se podrán actualizar, por lo que no es recomendable para ADD, UPDATE o DELETE

// operacion de solo lectura
var libros = context.Libros
	.AsNoTracking()
	.Where(l => l.Autor == "Something")
	.ToList();

Read More

Data Models Entity Framework Core

You can easily mark fields for a model which are primary key or are required.

public class User
{
	[Key]
	public int Id { get; set; }
	
	[Required(ErrorMessage = "Name is mandatory")]
	public string Name { get; set; }
	
	public string Telephone { get; set; }
	
	public string Mobile { get; set; }
	
	[Required(ErrorMessage = "Email is mandatory")]
	public string Email { get; set; }
}

Read More