ABP框架服务层的接口与实现(增删改查)
public interface ITaskAppService : IApplicationService { IList<TaskDto> GetAllTasks();//所有 GetTasksOutput GetTasks(GetTasksInput input);//根据查询参数 获取结果列表 PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input);//根据查询参数,返回被分页的结果列表 TaskDto GetTaskById(int taskId); TaskCacheItem GetTaskFromCacheById(int taskId); Task<TaskDto> GetTaskByIdAsync(int taskId); void UpdateTask(UpdateTaskInput input); int CreateTask(CreateTaskInput input); void DeleteTask(int taskId); }
public IList<TaskDto> GetAllTasks() { var tasks = _taskRepository.GetAll().OrderByDescending(t => t.CreationTime).ToList(); return Mapper.Map<IList<TaskDto>>(tasks);//因为已经定义了映射转换规则 } //多条件查询 public GetTasksOutput GetTasks(GetTasksInput input) { var query = _taskRepository.GetAll().Include(t => t.AssignedPerson) .WhereIf(input.State.HasValue, t => t.State == input.State.Value) .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter)) .WhereIf(input.AssignedPersonId.HasValue, t => t.AssignedPersonId == input.AssignedPersonId.Value); //WhereIf为Linq扩展方法,表示如果第一个表达式为true,则加第二个过滤条件 //排序 if (!string.IsNullOrEmpty(input.Sorting))//排序字段是否有值 query = query.OrderBy(input.Sorting); else query = query.OrderByDescending(t => t.CreationTime); var taskList = query.ToList(); //Used AutoMapper to automatically convert List<Task> to List<TaskDto>. var tr = Mapper.Map<List<TaskDto>>(taskList); return new GetTasksOutput { Tasks = tr }; //return new GetTasksOutput //{ // Tasks = Mapper.Map<List<TaskDto>>(taskList) //}; } public PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input) { //初步过滤 var query = _taskRepository.GetAll().Include(t => t.AssignedPerson) .WhereIf(input.State.HasValue, t => t.State == input.State.Value) .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter)) .WhereIf(input.AssignedPersonId.HasValue, t => t.AssignedPersonId == input.AssignedPersonId.Value); //排序 query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(input.Sorting) : query.OrderByDescending(t => t.CreationTime); //获取总数 var tasksCount = query.Count(); //默认的分页方式 //var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList(); //ABP提供了扩展方法PageBy分页方式 var taskList = query.PageBy(input).ToList(); return new PagedResultDto<TaskDto>(tasksCount, taskList.MapTo<List<TaskDto>>()); } public TaskDto GetTaskById(int taskId) { var task = _taskRepository.Get(taskId); return task.MapTo<TaskDto>(); } public TaskCacheItem GetTaskFromCacheById(int taskId) { return _taskCache[taskId]; } public async Task<TaskDto> GetTaskByIdAsync(int taskId) { //Called specific GetAllWithPeople method of task repository. var task = await _taskRepository.GetAsync(taskId); //Used AutoMapper to automatically convert List<Task> to List<TaskDto>. return task.MapTo<TaskDto>(); } public void UpdateTask(UpdateTaskInput input) { //We can use Logger, it's defined in ApplicationService base class. Logger.Info("Updating a task for input: " + input); //获取是否有权限 bool canAssignTaskToOther = PermissionChecker.IsGranted(PermissionNames.Pages_Tasks_AssignPerson); //如果任务已经分配且未分配给自己,且不具有分配任务权限,则抛出异常 if (input.AssignedPersonId.HasValue && input.AssignedPersonId.Value != AbpSession.GetUserId() && !canAssignTaskToOther) { throw new AbpAuthorizationException("没有分配任务给他人的权限!"); } var updateTask = Mapper.Map<Task>(input); _taskRepository.Update(updateTask); } public int CreateTask(CreateTaskInput input) { //We can use Logger, it's defined in ApplicationService class. Logger.Info("Creating a task for input: " + input); //判断用户是否有权限 if (input.AssignedPersonId.HasValue && input.AssignedPersonId.Value !=AbpSession.GetUserId()) PermissionChecker.Authorize(PermissionNames.Pages_Tasks_AssignPerson); var task = Mapper.Map<Task>(input); int result = _taskRepository.InsertAndGetId(task); //只有创建成功才发送邮件和通知 if (result > 0) { task.CreationTime = Clock.Now; if (input.AssignedPersonId.HasValue) { task.AssignedPerson = _userRepository.Load(input.AssignedPersonId.Value); var message = "You hava been assigned one task into your todo list."; //TODO:需要重新配置QQ邮箱密码 //SmtpEmailSender emailSender = new SmtpEmailSender(_smtpEmialSenderConfig); //emailSender.Send("ysjshengjie@qq.com", task.AssignedPerson.EmailAddress, "New Todo item", message); _notificationPublisher.Publish("NewTask", new MessageNotificationData(message), null, NotificationSeverity.Info, new[] { task.AssignedPerson.ToUserIdentifier() }); } } return result; } [AbpAuthorize(PermissionNames.Pages_Tasks_Delete)] public void DeleteTask(int taskId) { var task = _taskRepository.Get(taskId); if (task != null) _taskRepository.Delete(task); }
仓储层再领域层定义,在基础层实现
领域层的定义,源码位置:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 { /// <summary> /// This interface is implemented by all repositories to ensure implementation of fixed methods. /// </summary> /// <typeparam name="TEntity">Main Entity type this repository works on</typeparam> /// <typeparam name="TPrimaryKey">Primary key type of the entity</typeparam> public interface IRepository<TEntity, TPrimaryKey> : IRepository where TEntity : class, IEntity<TPrimaryKey> { #region Select/Get/Query /// <summary> /// Used to get a IQueryable that is used to retrieve entities from entire table. /// </summary> /// <returns>IQueryable to be used to select entities from database</returns> IQueryable<TEntity> GetAll(); /// <summary> /// Used to get a IQueryable that is used to retrieve entities from entire table. /// One or more /// </summary> /// <param name="propertySelectors">A list of include expressions.</param> /// <returns>IQueryable to be used to select entities from database</returns> IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] propertySelectors); /// <summary> /// Used to get all entities. /// </summary> /// <returns>List of all entities</returns> List<TEntity> GetAllList(); /// <summary> /// Used to get all entities. /// </summary> /// <returns>List of all entities</returns> Task<List<TEntity>> GetAllListAsync(); /// <summary> /// Used to get all entities based on given <paramref name="predicate"/>. /// </summary> /// <param name="predicate">A condition to filter entities</param> /// <returns>List of all entities</returns> List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Used to get all entities based on given <paramref name="predicate"/>. /// </summary> /// <param name="predicate">A condition to filter entities</param> /// <returns>List of all entities</returns> Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Used to run a query over entire entities. /// <see cref="UnitOfWorkAttribute"/> attribute is not always necessary (as opposite to <see cref="GetAll"/>) /// if <paramref name="queryMethod"/> finishes IQueryable with ToList, FirstOrDefault etc.. /// </summary> /// <typeparam name="T">Type of return value of this method</typeparam> /// <param name="queryMethod">This method is used to query over entities</param> /// <returns>Query result</returns> T Query<T>(Func<IQueryable<TEntity>, T> queryMethod); /// <summary> /// Gets an entity with given primary key. /// </summary> /// <param name="id">Primary key of the entity to get</param> /// <returns>Entity</returns> TEntity Get(TPrimaryKey id); /// <summary> /// Gets an entity with given primary key. /// </summary> /// <param name="id">Primary key of the entity to get</param> /// <returns>Entity</returns> Task<TEntity> GetAsync(TPrimaryKey id); /// <summary> /// Gets exactly one entity with given predicate. /// Throws exception if no entity or more than one entity. /// </summary> /// <param name="predicate">Entity</param> TEntity Single(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets exactly one entity with given predicate. /// Throws exception if no entity or more than one entity. /// </summary> /// <param name="predicate">Entity</param> Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets an entity with given primary key or null if not found. /// </summary> /// <param name="id">Primary key of the entity to get</param> /// <returns>Entity or null</returns> TEntity FirstOrDefault(TPrimaryKey id); /// <summary> /// Gets an entity with given primary key or null if not found. /// </summary> /// <param name="id">Primary key of the entity to get</param> /// <returns>Entity or null</returns> Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id); /// <summary> /// Gets an entity with given given predicate or null if not found. /// </summary> /// <param name="predicate">Predicate to filter entities</param> TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets an entity with given given predicate or null if not found. /// </summary> /// <param name="predicate">Predicate to filter entities</param> Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Creates an entity with given primary key without database access. /// </summary> /// <param name="id">Primary key of the entity to load</param> /// <returns>Entity</returns> TEntity Load(TPrimaryKey id); #endregion #region Insert /// <summary> /// Inserts a new entity. /// </summary> /// <param name="entity">Inserted entity</param> TEntity Insert(TEntity entity); /// <summary> /// Inserts a new entity. /// </summary> /// <param name="entity">Inserted entity</param> Task<TEntity> InsertAsync(TEntity entity); /// <summary> /// Inserts a new entity and gets it's Id. /// It may require to save current unit of work /// to be able to retrieve id. /// </summary> /// <param name="entity">Entity</param> /// <returns>Id of the entity</returns> TPrimaryKey InsertAndGetId(TEntity entity); /// <summary> /// Inserts a new entity and gets it's Id. /// It may require to save current unit of work /// to be able to retrieve id. /// </summary> /// <param name="entity">Entity</param> /// <returns>Id of the entity</returns> Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity); /// <summary> /// Inserts or updates given entity depending on Id's value. /// </summary> /// <param name="entity">Entity</param> TEntity InsertOrUpdate(TEntity entity); /// <summary> /// Inserts or updates given entity depending on Id's value. /// </summary> /// <param name="entity">Entity</param> Task<TEntity> InsertOrUpdateAsync(TEntity entity); /// <summary> /// 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. /// </summary> /// <param name="entity">Entity</param> /// <returns>Id of the entity</returns> TPrimaryKey InsertOrUpdateAndGetId(TEntity entity); /// <summary> /// 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. /// </summary> /// <param name="entity">Entity</param> /// <returns>Id of the entity</returns> Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity); #endregion #region Update /// <summary> /// Updates an existing entity. /// </summary> /// <param name="entity">Entity</param> TEntity Update(TEntity entity); /// <summary> /// Updates an existing entity. /// </summary> /// <param name="entity">Entity</param> Task<TEntity> UpdateAsync(TEntity entity); /// <summary> /// Updates an existing entity. /// </summary> /// <param name="id">Id of the entity</param> /// <param name="updateAction">Action that can be used to change values of the entity</param> /// <returns>Updated entity</returns> TEntity Update(TPrimaryKey id, Action<TEntity> updateAction); /// <summary> /// Updates an existing entity. /// </summary> /// <param name="id">Id of the entity</param> /// <param name="updateAction">Action that can be used to change values of the entity</param> /// <returns>Updated entity</returns> Task<TEntity> UpdateAsync(TPrimaryKey id, Func<TEntity, Task> updateAction); #endregion #region Delete /// <summary> /// Deletes an entity. /// </summary> /// <param name="entity">Entity to be deleted</param> void Delete(TEntity entity); /// <summary> /// Deletes an entity. /// </summary> /// <param name="entity">Entity to be deleted</param> Task DeleteAsync(TEntity entity); /// <summary> /// Deletes an entity by primary key. /// </summary> /// <param name="id">Primary key of the entity</param> void Delete(TPrimaryKey id); /// <summary> /// Deletes an entity by primary key. /// </summary> /// <param name="id">Primary key of the entity</param> Task DeleteAsync(TPrimaryKey id); /// <summary> /// 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. /// </summary> /// <param name="predicate">A condition to filter entities</param> void Delete(Expression<Func<TEntity, bool>> predicate); /// <summary> /// 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. /// </summary> /// <param name="predicate">A condition to filter entities</param> Task DeleteAsync(Expression<Func<TEntity, bool>> predicate); #endregion #region Aggregates /// <summary> /// Gets count of all entities in this repository. /// </summary> /// <returns>Count of entities</returns> int Count(); /// <summary> /// Gets count of all entities in this repository. /// </summary> /// <returns>Count of entities</returns> Task<int> CountAsync(); /// <summary> /// Gets count of all entities in this repository based on given <paramref name="predicate"/>. /// </summary> /// <param name="predicate">A method to filter count</param> /// <returns>Count of entities</returns> int Count(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets count of all entities in this repository based on given <paramref name="predicate"/>. /// </summary> /// <param name="predicate">A method to filter count</param> /// <returns>Count of entities</returns> Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets count of all entities in this repository (use if expected return value is greather than <see cref="int.MaxValue"/>. /// </summary> /// <returns>Count of entities</returns> long LongCount(); /// <summary> /// Gets count of all entities in this repository (use if expected return value is greather than <see cref="int.MaxValue"/>. /// </summary> /// <returns>Count of entities</returns> Task<long> LongCountAsync(); /// <summary> /// Gets count of all entities in this repository based on given <paramref name="predicate"/> /// (use this overload if expected return value is greather than <see cref="int.MaxValue"/>). /// </summary> /// <param name="predicate">A method to filter count</param> /// <returns>Count of entities</returns> long LongCount(Expression<Func<TEntity, bool>> predicate); /// <summary> /// Gets count of all entities in this repository based on given <paramref name="predicate"/> /// (use this overload if expected return value is greather than <see cref="int.MaxValue"/>). /// </summary> /// <param name="predicate">A method to filter count</param> /// <returns>Count of entities</returns> Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate); #endregion } }
aspnetboilerplate-dev\aspnetboilerplate-dev\src\Abp\Domain\Repositories\IRepositoryOfTEntityAndTPrimaryKey.cs
基础层实现的源码位置:
aspnetboilerplate-dev\aspnetboilerplate-dev\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Abp.Collections.Extensions; using Abp.Domain.Entities; using Abp.Domain.Repositories; namespace Abp.EntityFramework.Repositories { /// <summary> /// Implements IRepository for Entity Framework. /// </summary> /// <typeparam name="TDbContext">DbContext which contains <typeparamref name="TEntity"/>.</typeparam> /// <typeparam name="TEntity">Type of the Entity for this repository</typeparam> /// <typeparam name="TPrimaryKey">Primary key of the entity</typeparam> public class EfRepositoryBase<TDbContext, TEntity, TPrimaryKey> : AbpRepositoryBase<TEntity, TPrimaryKey>, IRepositoryWithDbContext where TEntity : class, IEntity<TPrimaryKey> where TDbContext : DbContext { /// <summary> /// Gets EF DbContext object. /// </summary> public virtual TDbContext Context { get { return _dbContextProvider.GetDbContext(MultiTenancySide); } } /// <summary> /// Gets DbSet for given entity. /// </summary> public virtual DbSet<TEntity> Table { get { return Context.Set<TEntity>(); } } private readonly IDbContextProvider<TDbContext> _dbContextProvider; /// <summary> /// Constructor /// </summary> /// <param name="dbContextProvider"></param> public EfRepositoryBase(IDbContextProvider<TDbContext> dbContextProvider) { _dbContextProvider = dbContextProvider; } public override IQueryable<TEntity> GetAll() { return Table; } public override IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] propertySelectors) { if (propertySelectors.IsNullOrEmpty()) { return GetAll(); } var query = GetAll(); foreach (var propertySelector in propertySelectors) { query = query.Include(propertySelector); } return query; } public override async Task<List<TEntity>> GetAllListAsync() { return await GetAll().ToListAsync(); } public override async Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate) { return await GetAll().Where(predicate).ToListAsync(); } public override async Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate) { return await GetAll().SingleAsync(predicate); } public override async Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id) { return await GetAll().FirstOrDefaultAsync(CreateEqualityExpressionForId(id)); } public override async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate) { return await GetAll().FirstOrDefaultAsync(predicate); } public override TEntity Insert(TEntity entity) { return Table.Add(entity); } public override Task<TEntity> InsertAsync(TEntity entity) { return Task.FromResult(Table.Add(entity)); } public override TPrimaryKey InsertAndGetId(TEntity entity) { entity = Insert(entity); if (entity.IsTransient()) { Context.SaveChanges(); } return entity.Id; } public override async Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity) { entity = await InsertAsync(entity); if (entity.IsTransient()) { await Context.SaveChangesAsync(); } return entity.Id; } public override TPrimaryKey InsertOrUpdateAndGetId(TEntity entity) { entity = InsertOrUpdate(entity); if (entity.IsTransient()) { Context.SaveChanges(); } return entity.Id; } public override async Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity) { entity = await InsertOrUpdateAsync(entity); if (entity.IsTransient()) { await Context.SaveChangesAsync(); } return entity.Id; } public override TEntity Update(TEntity entity) { AttachIfNot(entity); Context.Entry(entity).State = EntityState.Modified; return entity; } public override Task<TEntity> UpdateAsync(TEntity entity) { AttachIfNot(entity); Context.Entry(entity).State = EntityState.Modified; return Task.FromResult(entity); } public override void Delete(TEntity entity) { AttachIfNot(entity); Table.Remove(entity); } public override void Delete(TPrimaryKey id) { var entity = Table.Local.FirstOrDefault(ent => EqualityComparer<TPrimaryKey>.Default.Equals(ent.Id, id)); if (entity == null) { entity = FirstOrDefault(id); if (entity == null) { return; } } Delete(entity); } public override async Task<int> CountAsync() { return await GetAll().CountAsync(); } public override async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate) { return await GetAll().Where(predicate).CountAsync(); } public override async Task<long> LongCountAsync() { return await GetAll().LongCountAsync(); } public override async Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate) { return await GetAll().Where(predicate).LongCountAsync(); } protected virtual void AttachIfNot(TEntity entity) { if (!Table.Local.Contains(entity)) { Table.Attach(entity); } } public DbContext GetDbContext() { return Context; } } }
Nhibernate 实现:
源码路径:
aspnetboilerplate-dev\aspnetboilerplate-dev\src\Abp.NHibernate\NHibernate\Repositories\NhRepositoryBaseOfTEntityAndTPrimaryKey.cs
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Abp.Collections.Extensions; using Abp.Domain.Entities; using Abp.Domain.Repositories; using NHibernate; using NHibernate.Linq; using NHibernate.Util; namespace Abp.NHibernate.Repositories { /// <summary> /// Base class for all repositories those uses NHibernate. /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <typeparam name="TPrimaryKey">Primary key type of the entity</typeparam> public class NhRepositoryBase<TEntity, TPrimaryKey> : AbpRepositoryBase<TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey> { /// <summary> /// Gets the NHibernate session object to perform database operations. /// </summary> public virtual ISession Session { get { return _sessionProvider.Session; } } private readonly ISessionProvider _sessionProvider; /// <summary> /// Creates a new <see cref="NhRepositoryBase{TEntity,TPrimaryKey}"/> object. /// </summary> /// <param name="sessionProvider">A session provider to obtain session for database operations</param> public NhRepositoryBase(ISessionProvider sessionProvider) { _sessionProvider = sessionProvider; } public override IQueryable<TEntity> GetAll() { return Session.Query<TEntity>(); } public override IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] propertySelectors) { if (propertySelectors.IsNullOrEmpty()) { return GetAll(); } var query = GetAll(); foreach (var propertySelector in propertySelectors) { //TODO: Test if NHibernate supports multiple fetch. query = query.Fetch(propertySelector); } return query; } public override TEntity FirstOrDefault(TPrimaryKey id) { return Session.Get<TEntity>(id); } public override TEntity Load(TPrimaryKey id) { return Session.Load<TEntity>(id); } public override TEntity Insert(TEntity entity) { Session.Save(entity); return entity; } public override TEntity InsertOrUpdate(TEntity entity) { Session.SaveOrUpdate(entity); return entity; } public override Task<TEntity> InsertOrUpdateAsync(TEntity entity) { return Task.FromResult(InsertOrUpdate(entity)); } public override TEntity Update(TEntity entity) { Session.Update(entity); return entity; } public override void Delete(TEntity entity) { if (entity is ISoftDelete) { (entity as ISoftDelete).IsDeleted = true; Update(entity); } else { Session.Delete(entity); } } public override void Delete(TPrimaryKey id) { Delete(Session.Load<TEntity>(id)); } } }