using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Abp.Domain.Entities;
using Abp.Domain.Uow;
namespace Abp.Domain.Repositories
{
///
/// This interface is implemented by all repositories to ensure implementation of fixed methods.
///
/// Main Entity type this repository works on
/// Primary key type of the entity
public interface IRepository : IRepository where TEntity : class, IEntity
{
#region Select/Get/Query
///
/// Used to get a IQueryable that is used to retrieve entities from entire table.
///
/// IQueryable to be used to select entities from database
IQueryable GetAll();
///
/// Used to get a IQueryable that is used to retrieve entities from entire table.
/// One or more
///
/// A list of include expressions.
/// IQueryable to be used to select entities from database
IQueryable GetAllIncluding(params Expression>[] propertySelectors);
///
/// Used to get all entities.
///
/// List of all entities
List GetAllList();
///
/// Used to get all entities.
///
/// List of all entities
Task> GetAllListAsync();
///
/// Used to get all entities based on given .
///
/// A condition to filter entities
/// List of all entities
List GetAllList(Expression> predicate);
///
/// Used to get all entities based on given .
///
/// A condition to filter entities
/// List of all entities
Task> GetAllListAsync(Expression> predicate);
///
/// Used to run a query over entire entities.
/// attribute is not always necessary (as opposite to )
/// if finishes IQueryable with ToList, FirstOrDefault etc..
///
/// Type of return value of this method
/// This method is used to query over entities
/// Query result
T Query(Func, T> queryMethod);
///
/// Gets an entity with given primary key.
///
/// Primary key of the entity to get
/// Entity
TEntity Get(TPrimaryKey id);
///
/// Gets an entity with given primary key.
///
/// Primary key of the entity to get
/// Entity
Task GetAsync(TPrimaryKey id);
///
/// Gets exactly one entity with given predicate.
/// Throws exception if no entity or more than one entity.
///
/// Entity
TEntity Single(Expression> predicate);
///
/// Gets exactly one entity with given predicate.
/// Throws exception if no entity or more than one entity.
///
/// Entity
Task SingleAsync(Expression> predicate);
///
/// Gets an entity with given primary key or null if not found.
///
/// Primary key of the entity to get
/// Entity or null
TEntity FirstOrDefault(TPrimaryKey id);
///
/// Gets an entity with given primary key or null if not found.
///
/// Primary key of the entity to get
/// Entity or null
Task FirstOrDefaultAsync(TPrimaryKey id);
///
/// Gets an entity with given given predicate or null if not found.
///
/// Predicate to filter entities
TEntity FirstOrDefault(Expression> predicate);
///
/// Gets an entity with given given predicate or null if not found.
///
/// Predicate to filter entities
Task FirstOrDefaultAsync(Expression> predicate);
///
/// Creates an entity with given primary key without database access.
///
/// Primary key of the entity to load
/// Entity
TEntity Load(TPrimaryKey id);
#endregion
#region Insert
///
/// Inserts a new entity.
///
/// Inserted entity
TEntity Insert(TEntity entity);
///
/// Inserts a new entity.
///
/// Inserted entity
Task InsertAsync(TEntity entity);
///
/// Inserts a new entity and gets it's Id.
/// It may require to save current unit of work
/// to be able to retrieve id.
///
/// Entity
/// Id of the entity
TPrimaryKey InsertAndGetId(TEntity entity);
///
/// Inserts a new entity and gets it's Id.
/// It may require to save current unit of work
/// to be able to retrieve id.
///
/// Entity
/// Id of the entity
Task InsertAndGetIdAsync(TEntity entity);
///
/// Inserts or updates given entity depending on Id's value.
///
/// Entity
TEntity InsertOrUpdate(TEntity entity);
///
/// Inserts or updates given entity depending on Id's value.
///
/// Entity
Task InsertOrUpdateAsync(TEntity entity);
///
/// Inserts or updates given entity depending on Id's value.
/// Also returns Id of the entity.
/// It may require to save current unit of work
/// to be able to retrieve id.
///
/// Entity
/// Id of the entity
TPrimaryKey InsertOrUpdateAndGetId(TEntity entity);
///
/// Inserts or updates given entity depending on Id's value.
/// Also returns Id of the entity.
/// It may require to save current unit of work
/// to be able to retrieve id.
///
/// Entity
/// Id of the entity
Task InsertOrUpdateAndGetIdAsync(TEntity entity);
#endregion
#region Update
///
/// Updates an existing entity.
///
/// Entity
TEntity Update(TEntity entity);
///
/// Updates an existing entity.
///
/// Entity
Task UpdateAsync(TEntity entity);
///
/// Updates an existing entity.
///
/// Id of the entity
/// Action that can be used to change values of the entity
/// Updated entity
TEntity Update(TPrimaryKey id, Action updateAction);
///
/// Updates an existing entity.
///
/// Id of the entity
/// Action that can be used to change values of the entity
/// Updated entity
Task UpdateAsync(TPrimaryKey id, Func updateAction);
#endregion
#region Delete
///
/// Deletes an entity.
///
/// Entity to be deleted
void Delete(TEntity entity);
///
/// Deletes an entity.
///
/// Entity to be deleted
Task DeleteAsync(TEntity entity);
///
/// Deletes an entity by primary key.
///
/// Primary key of the entity
void Delete(TPrimaryKey id);
///
/// Deletes an entity by primary key.
///
/// Primary key of the entity
Task DeleteAsync(TPrimaryKey id);
///
/// Deletes many entities by function.
/// Notice that: All entities fits to given predicate are retrieved and deleted.
/// This may cause major performance problems if there are too many entities with
/// given predicate.
///
/// A condition to filter entities
void Delete(Expression> predicate);
///
/// Deletes many entities by function.
/// Notice that: All entities fits to given predicate are retrieved and deleted.
/// This may cause major performance problems if there are too many entities with
/// given predicate.
///
/// A condition to filter entities
Task DeleteAsync(Expression> predicate);
#endregion
#region Aggregates
///
/// Gets count of all entities in this repository.
///
/// Count of entities
int Count();
///
/// Gets count of all entities in this repository.
///
/// Count of entities
Task CountAsync();
///
/// Gets count of all entities in this repository based on given .
///
/// A method to filter count
/// Count of entities
int Count(Expression> predicate);
///
/// Gets count of all entities in this repository based on given .
///
/// A method to filter count
/// Count of entities
Task CountAsync(Expression> predicate);
///
/// Gets count of all entities in this repository (use if expected return value is greather than .
///
/// Count of entities
long LongCount();
///
/// Gets count of all entities in this repository (use if expected return value is greather than .
///
/// Count of entities
Task LongCountAsync();
///
/// Gets count of all entities in this repository based on given
/// (use this overload if expected return value is greather than ).
///
/// A method to filter count
/// Count of entities
long LongCount(Expression> predicate);
///
/// Gets count of all entities in this repository based on given
/// (use this overload if expected return value is greather than ).
///
/// A method to filter count
/// Count of entities
Task LongCountAsync(Expression> predicate);
#endregion
}
}