Skip to content

Repository

Hamed ZVand edited this page Nov 10, 2019 · 3 revisions

This class provides a lightweight generic repository pattern

  • Support composite key (multiple Ids) entities
  • Not restricted to a specific interface for Entity and Key

Installation (based on Entity Framework provider) (other providers)

You should install Alamut.Data.EF with NuGet:

Install-Package Alamut.Data.EF

Or via the .NET Core command-line interface:

dotnet add package Alamut.Data.EF 

Setup

in Startup file register the generic repository:

services.AddScoped(typeof(Alamut.Data.Repository.IRepository<>), typeof(Alamut.Data.EF.Repository<>));

Methods:

  • Task<TEntity> GetById(params object[] id)
    gets an Entity by id
Blog result = await _blogRepository.GetById(id);
  • Task<IPaginated<TEntity>> GetPaginated(IPaginatedCriteria criteria = null)
    gets a list of Entities in Paginated data-type filtered by provided criteria or default
IPaginated<Blog> actual = await _blogRepository.GetPaginated(new PaginatedCriteria(2, 10));
  • void Add(TEntity entity)
    adds an Entity to the current context
var blog = new Blog
{
    Url = "https://github.com/SorenZ/Alamut.DotNet",
    Rating = 5
};
// act
_blogRepository.Add(blog);
  • void AddRange(IEnumerable<TEntity> entities)
    adds a list of Entities to the current Context
var blogs= new[]
{
    new Blog
    {
        Url = "https://github.com/SorenZ/Alamut.Data",
        Rating = 5
    },
    new Blog
    {
        Url = "https://github.com/SorenZ/Alamut.AspNet",
        Rating = 4
    }
};
// act
repository.AddRange(blogs);
  • void Update(TEntity entity)
    updates an Entity in the current Context (attached and unattached entities)
var blog = new Blog
{
    Id = entity.Id,
    Rating = 10,
    Posts = null,
};
// act
repository.Update(blog);
  • Task UpdateFieldById<TField>(object id, Expression<Func<TEntity, TField>> memberExpression, TField value);
    updates an item (one field) by expression member selector filter by id
await _blogRepository.UpdateFieldById(1 , blog => blog.Rating, 100);
  • Task UpdateField<TField>(Expression<Func<TEntity, bool>> filterExpression, Expression<Func<TEntity, TField>> memberExpression, TField value);
    updates an item (one field) by expression member selector filter by provided filterExpression predicate
await _blogRepository.UpdateField(blog => blog.Id == 1, blog => blog.Rating, 100);
  • Task GenericUpdate(object id, Dictionary<string, object> fieldset)
    updates fieldset (filed, value) in the database filter by id
var fieldset = new Dictionary<string, object>
{
    {"Rating", 100},
    {"Url", "test"}
};
// act
await _blogRepository.GenericUpdate(expected.Id, fieldset);
  • Task DeleteById(params object[] id)
    deletes an Entity by id in the current Context
await _blogRepository.DeleteById(id);
  • void Delete(TEntity entity)
    deletes an Entity by changing the state of it
_blogRepository.Delete(blog);
  • void DeleteMany(Expression<Func<TEntity, bool>> predicate)
    deletes multiple Entities filter by predicate (in current Context)
_blogRepository.DeleteMany(d => true);
  • Task<Result> CommitAsync()
    commit changes to underlying database.
    if commit changes the state of the database return success Result, otherwise return error Result
[HttpDelete("{id}")]
public async Task<ActionResult<Result>> Delete(int id)
{
    await _blogRepository.DeleteById(id);
    var result = await _blogRepository.CommitAsync(CancellationToken.None);
    return result ? Ok(result) : StatusCode(result.StatusCode, result);
}

Properties:

  • IQueryable<TEntity> Queryable { get; }
    provides a queryable source of elements.
    the Queryable has not been tracked in sql repositories
// arrange
var repository = new Repository<Blog>(_dbContext);
var expected = _dbContext.Blogs.AsQueryable();

// act
var actual = repository.Queryable;

// assert
Assert.Equal(expected, actual);