# EntityFrameworkRepository<TEntity>

`class` `public`

```csharp
namespace Core.Data.Repositories;

public class EntityFrameworkRepository<TEntity> : IRepository<TEntity>
    where TEntity : class
```

A generic repository implementation using Entity Framework Core to perform standard CRUD operations. Abstracting the underlying [`DbContext`](../Core.Data/DbContext.md), this class provides a foundational data access layer that can be easily inherited or used directly.

* **TEntity**: The entity type managed by the repository.

```csharp
// Example usage in a standard .NET Dependency Injection container
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IRepository<User>, EntityFrameworkRepository<User>>();
```

## Constructors

{% member id="ctor" %}
```csharp
public EntityFrameworkRepository(DbContext dbContext)
```

Initializes a new instance of the `EntityFrameworkRepository<TEntity>` class.

* **dbContext**: The database context to use.

**Throws** `ArgumentNullException`: `dbContext` is `null`.

{% /member %}

## Delegates

{% member id="entitychangedeventhandler" %}
```csharp
public delegate void EntityChangedEventHandler(
    object sender,
    EntityChangedEventArgs<TEntity> e
);
```

Represents the method that will handle events triggered when an entity undergoes a lifecycle change.

* **sender**: The source of the event, typically the repository instance.
* **e**: An object that contains the event data.

{% /member %}

## Events

{% member id="entityadded" %}
```csharp
public event EntityChangedEventHandler? EntityAdded;
```

Occurs when a new entity is successfully added to the repository.

> **Remarks**: This event is triggered synchronously after the Add operation is performed on the DbSet, but before SaveChanges is called.

{% /member %}

## Fields

{% member id="dbcontext" %}
```csharp
protected readonly DbContext _dbContext;
```

The underlying database context instance used for data access operations.

> **Remarks**: Derived classes can access this field directly to perform operations not exposed by the generic interface.

{% /member %}

## Properties

{% member id="context" %}
```csharp
public virtual DbContext Context { get; }
```

Gets the active database context for the current scope.

**Value**: The current DbContext instance injected during repository construction.

{% /member %}

{% member id="maxpagesize" %}
```csharp
public int MaxPageSize { get; set; }
```

Gets or sets the maximum page size used by [`ListAsync`](#listasync).

{% /member %}

## Static Methods

{% member id="createtransient" %}
```csharp
public static EntityFrameworkRepository<TEntity> CreateTransient(
    DbContext context
)
```

Creates a transient instance of the repository using the provided context.

* **context**: The database context to use.

**Returns**: A new, non-dependency-injected instance of the repository.

> **Remarks**: Use this method sparingly; typically repositories should be resolved from the DI container.

{% /member %}

## Methods

{% member id="addasync" %}
```csharp
public async Task<TEntity> AddAsync(
    TEntity entity,
    CancellationToken cancellationToken = default
)
```

Asynchronously adds a new entity to the underlying database context. The entity will be inserted into the database upon the next save operation.

* **entity**: The entity instance to be inserted.
* **cancellationToken**: A token to observe for cancellation requests.

**Returns**: The inserted entity with any database-generated values applied.

> **Remarks**: This method calls AddAsync on the underlying DbSet. It does not automatically call [`SaveChangesAsync`](../Core.Data/DbContext.md#savechangesasync).

{% /member %}

{% member id="getbyidasync" %}
```csharp
public async Task<TEntity?> GetByIdAsync(
    object[] keyValues,
    CancellationToken cancellationToken = default
)
```

Asynchronously finds an entity with the given primary key values. If an entity with the given primary key values exists in the context, then it is returned immediately without making a request to the store.

* **keyValues**: The values of the primary key for the entity to be found.
* **cancellationToken**: A token to observe for cancellation requests.

**Returns**: The entity found, or null if no entity is found.

{% /member %}

{% member id="listasync" %}
```csharp
public Task<IReadOnlyList<TEntity>> ListAsync(
    ISpecification<TEntity> specification,
    CancellationToken cancellationToken = default
)
```

Evaluates the given specification and returns the matching entities as a read-only list. Useful for complex queries encapsulating filtering, sorting, and pagination.

* **specification**: The specification containing the query criteria to apply.
* **cancellationToken**: A token to observe for cancellation requests.

**Returns**: A read-only list of entities that match the specification criteria.

> **Remarks**: Implementations should evaluate the specification criteria against the DbSet queryable.

{% /member %}

{% member id="update" %}
```csharp
public void Update(TEntity entity)
```

Begins tracking the given entity and entries reachable from the given entity using the Modified state.

* **entity**: The entity instance to update.

> **Remarks**: Since this operation only changes tracking state, it is synchronous. Changes are pushed to the database only when SaveChanges is called.

{% /member %}

{% member id="onadded" %}
```csharp
protected virtual void OnAdded(TEntity entity)
```

Called after an entity has been added.

* **entity**: The added entity.

{% /member %}
