添加项目文件。
This commit is contained in:
942
Entities/Context/UnitOfWork/Repository.cs
Normal file
942
Entities/Context/UnitOfWork/Repository.cs
Normal file
@@ -0,0 +1,942 @@
|
||||
|
||||
|
||||
namespace SharedDATA.Api
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using SharedDATA.Context;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a default generic repository implements the <see cref="IRepository{TEntity}"/> interface.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
|
||||
{
|
||||
protected readonly DbContext _dbContext;
|
||||
protected readonly DbSet<TEntity> _dbSet;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Repository{TEntity}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dbContext">The database context.</param>
|
||||
public Repository(DbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
_dbSet = _dbContext.Set<TEntity>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the table name. This require the tables in the same database.
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <remarks>
|
||||
/// This only been used for supporting multiple tables in the same model. This require the tables in the same database.
|
||||
/// </remarks>
|
||||
public virtual void ChangeTable(string table)
|
||||
{
|
||||
if (_dbContext.Model.FindEntityType(typeof(TEntity)) is IConventionEntityType relational)
|
||||
{
|
||||
relational.SetTableName(table);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities. This method is not recommended
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IQueryable{TEntity}"/>.</returns>
|
||||
public IQueryable<TEntity> GetAll()
|
||||
{
|
||||
return _dbSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities. This method is not recommended
|
||||
/// </summary>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="disableTracking"><c>true</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>Ex: This method defaults to a read-only, no-tracking query.</remarks>
|
||||
public IQueryable<TEntity> GetAll(
|
||||
Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null, bool disableTracking = true, bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query);
|
||||
}
|
||||
else
|
||||
{
|
||||
return query;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPagedList{TEntity}"/> based on a predicate, orderby delegate and page information. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="pageIndex">The index of page.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual IPagedList<TEntity> GetPagedList(Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
int pageIndex = 0,
|
||||
int pageSize = 20,
|
||||
bool disableTracking = true,
|
||||
bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).ToPagedList(pageIndex, pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.ToPagedList(pageIndex, pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPagedList{TEntity}"/> based on a predicate, orderby delegate and page information. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="pageIndex">The index of page.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="cancellationToken">
|
||||
/// A <see cref="CancellationToken" /> to observe while waiting for the task to complete.
|
||||
/// </param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual Task<IPagedList<TEntity>> GetPagedListAsync(Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
int pageIndex = 0,
|
||||
int pageSize = 20,
|
||||
bool disableTracking = true,
|
||||
CancellationToken cancellationToken = default(CancellationToken),
|
||||
bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).ToPagedListAsync(pageIndex, pageSize, 0, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.ToPagedListAsync(pageIndex, pageSize, 0, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPagedList{TResult}"/> based on a predicate, orderby delegate and page information. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="selector">The selector for projection.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="pageIndex">The index of page.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TResult}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual IPagedList<TResult> GetPagedList<TResult>(Expression<Func<TEntity, TResult>> selector,
|
||||
Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
int pageIndex = 0,
|
||||
int pageSize = 20,
|
||||
bool disableTracking = true,
|
||||
bool ignoreQueryFilters = false)
|
||||
where TResult : class
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).Select(selector).ToPagedList(pageIndex, pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.Select(selector).ToPagedList(pageIndex, pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPagedList{TEntity}"/> based on a predicate, orderby delegate and page information. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="selector">The selector for projection.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="pageIndex">The index of page.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="cancellationToken">
|
||||
/// A <see cref="CancellationToken" /> to observe while waiting for the task to complete.
|
||||
/// </param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual Task<IPagedList<TResult>> GetPagedListAsync<TResult>(Expression<Func<TEntity, TResult>> selector,
|
||||
Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
int pageIndex = 0,
|
||||
int pageSize = 20,
|
||||
bool disableTracking = true,
|
||||
CancellationToken cancellationToken = default(CancellationToken),
|
||||
bool ignoreQueryFilters = false)
|
||||
where TResult : class
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).Select(selector).ToPagedListAsync(pageIndex, pageSize, 0, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.Select(selector).ToPagedListAsync(pageIndex, pageSize, 0, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first or default entity based on a predicate, orderby delegate and include delegate. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual TEntity GetFirstOrDefault(Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
bool disableTracking = true,
|
||||
bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual async Task<TEntity> GetFirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
bool disableTracking = true,
|
||||
bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return await orderBy(query).FirstOrDefaultAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await query.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first or default entity based on a predicate, orderby delegate and include delegate. This method default no-tracking query.
|
||||
/// </summary>
|
||||
/// <param name="selector">The selector for projection.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>This method default no-tracking query.</remarks>
|
||||
public virtual TResult GetFirstOrDefault<TResult>(Expression<Func<TEntity, TResult>> selector,
|
||||
Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
bool disableTracking = true,
|
||||
bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return orderBy(query).Select(selector).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
return query.Select(selector).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual async Task<TResult> GetFirstOrDefaultAsync<TResult>(Expression<Func<TEntity, TResult>> selector,
|
||||
Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
bool disableTracking = true, bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return await orderBy(query).Select(selector).FirstOrDefaultAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await query.Select(selector).FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses raw SQL queries to fetch the specified <typeparamref name="TEntity" /> data.
|
||||
/// </summary>
|
||||
/// <param name="sql">The raw SQL.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns>An <see cref="IQueryable{TEntity}" /> that contains elements that satisfy the condition specified by raw SQL.</returns>
|
||||
public virtual IQueryable<TEntity> FromSql(string sql, params object[] parameters) => _dbSet.FromSqlRaw(sql, parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Finds an entity with the given primary key values. If found, is attached to the context and returned. If no entity is found, then null is returned.
|
||||
/// </summary>
|
||||
/// <param name="keyValues">The values of the primary key for the entity to be found.</param>
|
||||
/// <returns>The found entity or null.</returns>
|
||||
public virtual TEntity Find(params object[] keyValues) => _dbSet.Find(keyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Finds an entity with the given primary key values. If found, is attached to the context and returned. If no entity is found, then null is returned.
|
||||
/// </summary>
|
||||
/// <param name="keyValues">The values of the primary key for the entity to be found.</param>
|
||||
/// <returns>A <see cref="Task{TEntity}" /> that represents the asynchronous insert operation.</returns>
|
||||
public virtual ValueTask<TEntity> FindAsync(params object[] keyValues) => _dbSet.FindAsync(keyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Finds an entity with the given primary key values. If found, is attached to the context and returned. If no entity is found, then null is returned.
|
||||
/// </summary>
|
||||
/// <param name="keyValues">The values of the primary key for the entity to be found.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete.</param>
|
||||
/// <returns>A <see cref="Task{TEntity}"/> that represents the asynchronous find operation. The task result contains the found entity or null.</returns>
|
||||
public virtual ValueTask<TEntity> FindAsync(object[] keyValues, CancellationToken cancellationToken) => _dbSet.FindAsync(keyValues, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the count based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns></returns>
|
||||
public virtual int Count(Expression<Func<TEntity, bool>> predicate = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return _dbSet.Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
return _dbSet.Count(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets async the count based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return await _dbSet.CountAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await _dbSet.CountAsync(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the long count based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns></returns>
|
||||
public virtual long LongCount(Expression<Func<TEntity, bool>> predicate = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return _dbSet.LongCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return _dbSet.LongCount(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets async the long count based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return await _dbSet.LongCountAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await _dbSet.LongCountAsync(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the max based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual T Max<T>(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, T>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return _dbSet.Max(selector);
|
||||
else
|
||||
return _dbSet.Where(predicate).Max(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the async max based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual async Task<T> MaxAsync<T>(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, T>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return await _dbSet.MaxAsync(selector);
|
||||
else
|
||||
return await _dbSet.Where(predicate).MaxAsync(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the min based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual T Min<T>(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, T>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return _dbSet.Min(selector);
|
||||
else
|
||||
return _dbSet.Where(predicate).Min(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the async min based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual async Task<T> MinAsync<T>(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, T>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return await _dbSet.MinAsync(selector);
|
||||
else
|
||||
return await _dbSet.Where(predicate).MinAsync(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the average based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual decimal Average(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, decimal>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return _dbSet.Average(selector);
|
||||
else
|
||||
return _dbSet.Where(predicate).Average(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the async average based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual async Task<decimal> AverageAsync(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, decimal>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return await _dbSet.AverageAsync(selector);
|
||||
else
|
||||
return await _dbSet.Where(predicate).AverageAsync(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sum based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual decimal Sum(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, decimal>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return _dbSet.Sum(selector);
|
||||
else
|
||||
return _dbSet.Where(predicate).Sum(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the async sum based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// /// <param name="selector"></param>
|
||||
/// <returns>decimal</returns>
|
||||
public virtual async Task<decimal> SumAsync(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, decimal>> selector = null)
|
||||
{
|
||||
if (predicate == null)
|
||||
return await _dbSet.SumAsync(selector);
|
||||
else
|
||||
return await _dbSet.Where(predicate).SumAsync(selector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exists based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="selector"></param>
|
||||
/// <returns></returns>
|
||||
public bool Exists(Expression<Func<TEntity, bool>> selector = null)
|
||||
{
|
||||
if (selector == null)
|
||||
{
|
||||
return _dbSet.Any();
|
||||
}
|
||||
else
|
||||
{
|
||||
return _dbSet.Any(selector);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the async exists based on a predicate.
|
||||
/// </summary>
|
||||
/// <param name="selector"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> selector = null)
|
||||
{
|
||||
if (selector == null)
|
||||
{
|
||||
return await _dbSet.AnyAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await _dbSet.AnyAsync(selector);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Inserts a new entity synchronously.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to insert.</param>
|
||||
public virtual TEntity Insert(TEntity entity)
|
||||
{
|
||||
return _dbSet.Add(entity).Entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a range of entities synchronously.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities to insert.</param>
|
||||
public virtual void Insert(params TEntity[] entities) => _dbSet.AddRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a range of entities synchronously.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities to insert.</param>
|
||||
public virtual void Insert(IEnumerable<TEntity> entities) => _dbSet.AddRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new entity asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to insert.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous insert operation.</returns>
|
||||
public virtual ValueTask<EntityEntry<TEntity>> InsertAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return _dbSet.AddAsync(entity, cancellationToken);
|
||||
|
||||
// Shadow properties?
|
||||
//var property = _dbContext.Entry(entity).Property("Created");
|
||||
//if (property != null) {
|
||||
//property.CurrentValue = DateTime.Now;
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a range of entities asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities to insert.</param>
|
||||
/// <returns>A <see cref="Task" /> that represents the asynchronous insert operation.</returns>
|
||||
public virtual Task InsertAsync(params TEntity[] entities) => _dbSet.AddRangeAsync(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a range of entities asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities to insert.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous insert operation.</returns>
|
||||
public virtual Task InsertAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default(CancellationToken)) => _dbSet.AddRangeAsync(entities, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
public virtual void Update(TEntity entity)
|
||||
{
|
||||
_dbSet.Update(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
public virtual void UpdateAsync(TEntity entity)
|
||||
{
|
||||
_dbSet.Update(entity);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified entities.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities.</param>
|
||||
public virtual void Update(params TEntity[] entities) => _dbSet.UpdateRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified entities.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities.</param>
|
||||
public virtual void Update(IEnumerable<TEntity> entities) => _dbSet.UpdateRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to delete.</param>
|
||||
public virtual void Delete(TEntity entity) => _dbSet.Remove(entity);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the entity by the specified primary key.
|
||||
/// </summary>
|
||||
/// <param name="id">The primary key value.</param>
|
||||
public virtual void Delete(object id)
|
||||
{
|
||||
// using a stub entity to mark for deletion
|
||||
var typeInfo = typeof(TEntity).GetTypeInfo();
|
||||
var key = _dbContext.Model.FindEntityType(typeInfo).FindPrimaryKey().Properties.FirstOrDefault();
|
||||
var property = typeInfo.GetProperty(key?.Name);
|
||||
if (property != null)
|
||||
{
|
||||
var entity = Activator.CreateInstance<TEntity>();
|
||||
property.SetValue(entity, id);
|
||||
_dbContext.Entry(entity).State = EntityState.Deleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
var entity = _dbSet.Find(id);
|
||||
if (entity != null)
|
||||
{
|
||||
Delete(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified entities.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities.</param>
|
||||
public virtual void Delete(params TEntity[] entities) => _dbSet.RemoveRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified entities.
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities.</param>
|
||||
public virtual void Delete(IEnumerable<TEntity> entities) => _dbSet.RemoveRange(entities);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities. This method is not recommended
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IQueryable{TEntity}"/>.</returns>
|
||||
public async Task<IList<TEntity>> GetAllAsync()
|
||||
{
|
||||
return await _dbSet.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities. This method is not recommended
|
||||
/// </summary>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <param name="orderBy">A function to order elements.</param>
|
||||
/// <param name="include">A function to include navigation properties</param>
|
||||
/// <param name="disableTracking"><c>true</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
|
||||
/// <param name="ignoreQueryFilters">Ignore query filters</param>
|
||||
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
|
||||
/// <remarks>Ex: This method defaults to a read-only, no-tracking query.</remarks>
|
||||
public async Task<IList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> predicate = null,
|
||||
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
|
||||
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
|
||||
bool disableTracking = true, bool ignoreQueryFilters = false)
|
||||
{
|
||||
IQueryable<TEntity> query = _dbSet;
|
||||
|
||||
if (disableTracking)
|
||||
{
|
||||
query = query.AsNoTracking();
|
||||
}
|
||||
|
||||
if (include != null)
|
||||
{
|
||||
query = include(query);
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
query = query.Where(predicate);
|
||||
}
|
||||
|
||||
if (ignoreQueryFilters)
|
||||
{
|
||||
query = query.IgnoreQueryFilters();
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
return await orderBy(query).ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change entity state for patch method on web api.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// /// <param name="state">The entity state.</param>
|
||||
public void ChangeEntityState(TEntity entity, EntityState state)
|
||||
{
|
||||
_dbContext.Entry(entity).State = state;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user