1 应用层(Application)
Application
|-- Dtos
|-- Services
1.1数据传输对象
序号 | 分类 | 名称 | CRUD |
---|---|---|---|
1 | InputDto | CreateDictCategoryInput | C |
2 | InputDto | GetAllDictCategoryInput | R |
3 | InputDto | GetDictCategoryInfoInput | R |
4 | InputDto | UpdateDictCategoryInput | U |
5 | InputDto | DeleteDictCategoryInput | D |
6 | OutputDto | DictCategoryOutput | R |
7 | OutputDto | GetAllDictCategoryOutput | R |
1.1.1 CreateDictCategoryInput
using System;
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class CreateDictCategoryInput
{
public string CategoryName { get; set; }
public string ParentCategoryId { get; set; }
public string CategoryDesc { get; set; }
public DateTime? CreationTime { get; set; }
public string CreatorUserId { get; set; }
public DateTime? LastModificationTime { get; set; }
public string LastModifierUserId { get; set; }
public DateTime? DeletionTime { get; set; }
public string DeleterUserId { get; set; }
public int? IsDeleted { get; set; }
public int? Status { get; set; }
public int? DisOrder { get; set; }
}
}
1.1.2 GetAllDictCategoryInput
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class GetAllDictCategoryInput
{
public string Token { get; set; }
}
}
1.1.3 GetDictCategoryInfoInput
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class GetDictCategoryInfoInput
{
public string CategoryId { get; set; }
}
}
1.1.4 UpdateDictCategoryInput
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class UpdateDictCategoryInput : CreateDictCategoryInput
{
public string CategoryId { get; set; }
}
}
1.1.5 DeleteDictCategoryInput
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class DeleteDictCategoryInput
{
public string CategoryId { get; set; }
}
}
1.1.6 DictCategoryOutput
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class DictCategoryOutput : UpdateDictCategoryInput { }
}
1.1.7 GetAllDictCategoryOutput
using System.Collections.Generic;
namespace Boer.Cloud.Bas.Application.DictCategoryMgr.Dtos
{
public class GetAllDictCategoryOutput
{
public List<DictCategoryOutput> DictCategories { get; set; }
}
}
2 DTO和实体间的自动映射
2.1 CreateMap
CreateMap<CreateDictCategoryInput, DictCategory>();
CreateMap<UpdateDictCategoryInput, DictCategory>();
CreateMap<DeleteDictCategoryInput, DictCategory>();
CreateMap<DictCategory, DictCategoryOutput>();
2.2 Map
var entity = Mapper.Map<CreateDictCategoryInput, DictCategory>(model);
var entity = Mapper.Map<UpdateDictCategoryInput, DictCategory>(model);
var entity = Mapper.Map<DeleteDictCategoryInput, DictCategory>(model);
jsonMsg.Result = Mapper.Map<DictCategory, DictCategoryOutput>(entity);
jsonMsg.Result = Mapper.Map<List<DictCategoryOutput>>(entity);
3 依赖注入
维基百科说:“依赖注入是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分。该模式分离了客户端依赖本身行为的创建,这使得程序设计变得松耦合,并遵循了依赖反转和单一职责原则。与服务定位器模式形成直接对比的是,它允许客户端了解客户端如何使用该系统找到依赖”。
3.1 依赖注入框架
微软提供的Unity,引用Microsoft.Practices.Unity.dll
和Microsoft.Practices.Unity.Configuration.dll
3.2 构造器注入
构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象。如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前解析注册的依赖关系并自行获得相应参数对象。
// AppService使用仓储进行数据库操作,它通过构造函数注入仓储对象的引用
// 构造函数自动注入我们所需要的类或接口
private readonly IUnitOfWork _uow = null;
private readonly IBasPolicy _policy = null;
public DictCategoryAppService(IUnitOfWork uow, IBasPolicy policy)
{
this._uow = uow;
this._policy = policy;
}
调用代码
// 创建容器
var container = new UnityContainer();
// 注册依赖对象
container.RegisterType<IDictCategoryAppService, DictCategoryAppService>(new HierarchicalLifetimeManager());
container.RegisterType<IUnitOfWork, Boer.Cloud.Bas.Domain.UnitOfWork.UnitOfWork>(new HierarchicalLifetimeManager());
container.RegisterType<IBasPolicy, BasPolicy>(new HierarchicalLifetimeManager());
2 领域层
2.1 仓储
2.1.1 查询
IRepository定义了通用的方法,从数据库中检索实体。
2.1.1.1 获得单个实体
TEntity Get(TPrimaryKey id);
Task<TEntity> GetAsync(TPrimaryKey id);
TEntity Single(Expression<Func<TEntity, bool>> predicate);
Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate);
TEntity FirstOrDefault(TPrimaryKey id);
Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id);
TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate);
Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);
TEntity Load(TPrimaryKey id);
Get方法用于获得一个给定主键(Id)的实体。如果在数据库中没有找到这个实体,就会抛出异常。Single方法和Get类似,但是它的参数是一个表达式而不是一个Id。因此,你可以使用Lambda表达式获得一个实体。样例用法:
var person = _personRepository.Get(42);
var person = _personRepository.Single(p => p.Name == "Halil İbrahim Kalkan");
注意:如果根据给定的条件没有查找出实体或者查出不止一个实体,那么Single方法会抛出异常。
FirstOrDefault是相似的,但是如果根据给的的Id或者表达式没有找到实体,那么就会返回null。如果对于给定的条件存在不止一个实体,那么会返回找到的第一个实体。
Load方法不会从数据库中检索实体,但是会创建一个用于懒加载的代理对象。如果你只用了Id属性,那么Entity实际上并没有检索到。只有你访问实体的其他属性,才会从数据库中检索。考虑到性能因素,这个就可以替换Get方法。这在NHiberbate中也实现了。如果ORM提供者没有实现它,那么Load方法会和Get方法一样地工作。
一些方法有用于async编程模型的异步(async)版本。
2.1.1.2 获得实体的列表
List<TEntity> GetAllList();
Task<List<TEntity>> GetAllListAsync();
List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate);
Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate);
IQueryable<TEntity> GetAll();
GetAllList从数据库中检索所有的实体。该方法的重载可以用于过滤实体。例子如下:
var allPeople = _personRepository.GetAllList();
var somePeople = _personRepository.GetAllList(person => person.IsActive && person.Age > 42);
GetAll返回的类型是IQueryable。因此,你可以在此方法之后添加Linq方法。例子如下:
//Example 1
var query = from person in _personRepository.GetAll()
where person.IsActive
orderby person.Name
select person;
var people = query.ToList();
//Example 2:
List<Person> personList2 = _personRepository.GetAll().Where(p => p.Name.Contains("H")).OrderBy(p => p.Name).Skip(40).Take(20).ToList();
有了GetAll方法,几乎所有的查询都可以使用Linq重写。甚至可以用在一个连接表达式中。
关于IQueryable
脱离了仓储方法调用GetAll()方法时,数据库连接必须要打开。这是因为IQueryable的延迟执行。直到调用ToList()方法或者在foreach循环中使用IQueryable(或者访问查询到的元素)时,才会执行数据库查询操作。因此,当调用ToList()方法时。数据库连接必须打开。这可以通过ABP中的UnitOfWork特性标记调用者方法来实现。注意:应用服务方法默认已经是UnitOfWork,因此,即使没有为应用服务层方法添加UnitOfWork特性,GetAll()方法也会正常工作。
这些方法也存在用于异步编程模型的asyn版本。
2.1.1.3 自定义返回值
也存在提供了IQueryable的额外方法,在调用的方法中不需要使用UnitOfWork。
T Query<T>(Func<IQueryable<TEntity>, T> queryMethod);
Query方法接受一个接收IQueryable的lambda(或方法),并返回任何对象的类型。例子如下:
var people = _personRepository.Query(q => q.Where(p => p.Name.Contains("H")).OrderBy(p => p.Name).ToList());
在该仓储方法中,因为执行了给定的lambda(或方法),它是在数据库连接打开的时候执行的。你可以返回实体列表,单个实体,一个投影或者执行了该查询的其他东西。
2.1.2 插入
IRepository接口定义了将一个实体插入数据库的简单方法:
TEntity Insert(TEntity entity);
Task<TEntity> InsertAsync(TEntity entity);
TPrimaryKey InsertAndGetId(TEntity entity);
Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity);
TEntity InsertOrUpdate(TEntity entity);
Task<TEntity> InsertOrUpdateAsync(TEntity entity);
TPrimaryKey InsertOrUpdateAndGetId(TEntity entity);
Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity);
Insert方法简化了将一个实体插入数据库,并将刚刚插入的实体返回。
InsertAndGetId方法返回了新插入实体的Id。如果实体的Id是自动增长的并且需要最新插入实体的Id,那么该方法很有用。InsertOrUpdate方法通过检查Id的值插入或更新给定的实体。最后,当插入或者更新之后,InsertOrUpdateAndGetId返回该实体的值。
所有的方法都存在用于异步编程模型的async版本。
2.1.3 更新
IRepository定义了一个方法来更新数据库中已存在的实体。它可以获得要更新的实体并返回相同的实体对象。
TEntity Update(TEntity entity);
Task<TEntity> UpdateAsync(TEntity entity);
2.1.4 删除
IRepository定义了从数据库中删除一个已存在的实体的方法。
void Delete(TEntity entity);
Task DeleteAsync(TEntity entity);
void Delete(TPrimaryKey id);
Task DeleteAsync(TPrimaryKey id);
void Delete(Expression<Func<TEntity, bool>> predicate);
Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);
第一个方法接受一个已存在的实体,第二个方法接受一个要删除的实体的Id。
最后一个方法接受一个删除符合给定条件的所有实体的方法。注意,匹配给定谓词的所有实体都会从数据库中检索到然后被删除。因此,小心使用它,如果给定的条件存在太多的实体,那么可能会造成性能问题。
2.1.5 其他
IRepository也提供了获得表中实体数量的方法。
int Count();
Task<int> CountAsync();
int Count(Expression<Func<TEntity, bool>> predicate);
Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate);
long LongCount();
Task<long> LongCountAsync();
long LongCount(Expression<Func<TEntity, bool>> predicate);
Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate);
2.1.6 关于异步方法
支持异步编程模型(APM)。因此,仓储方法有异步版本。下面是一个使用了异步模型的应用服务方法样例:
public class PersonAppService : AbpWpfDemoAppServiceBase, IPersonAppService
{
private readonly IRepository<Person> _personRepository;
public PersonAppService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
}
public async Task<GetPeopleOutput> GetAllPeople()
{
var people = await _personRepository.GetAllListAsync();
return new GetPeopleOutput
{
People = Mapper.Map<List<PersonDto>>(people)
};
}
}
GetAllPeople方法是异步的,并使用了具有await关键字的GetAllListAsync方法。
也许不是所有的ORM框架都支持Async,但是EntityFramework支持。如果不支持,异步仓储方法就会同步进行。比如,在EF中,InsertAsync和Insert是等效的,因为直到工作单元完成(Dbcontext.SaveChanges),EF才会将新的实体写入数据库。
工作单元
如何处理多个Repository库?
下面想象下如下场景,我们数据库中有多个表,那样我们需要为每个表创建一个Reporsitory类。(好多重复工作的说,其实这不是问题)
问题是关于 数据上下文(DbContext) 对象的。如果我们创建多个Repository类,是不是每一个都单独的包含一个 数据上下文对象?我们知道同时使用多个 数据上下文 会存在问题,那我们该怎么处理每个Repository都拥有自己的数据上下文 对象的问题?
来解决这个问题吧。为什么每个Repository要拥有一个数据上下文的实例呢?为什么不在一些地方创建一个它的实例,然后在repository被实例化的时候作为参数传递进去呢。现在这个新的类被命名为 UnitOfWork ,此类将负责创建数据上下文实例并移交到控制器的所有repository实例。
IUnitOfWork.cs
using Boer.Cloud.Bas.Domain.Repositories;
using System;
namespace Boer.Cloud.Bas.Domain.UnitOfWork
{
public interface IUnitOfWork : IDisposable
{
IBasRepositoryBase<T> Repository<T>() where T : class;
void SaveChanges();
}
}
UnitOfWork.cs
using Boer.Cloud.Bas.Domain.Repositories;
using Boer.Cloud.Bas.EntityFramework;
using Boer.Cloud.Bas.EntityFramework.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Boer.Cloud.Bas.Domain.UnitOfWork
{
public class UnitOfWork : IUnitOfWork
{
private BasDbContext dbContext = null;
public UnitOfWork()
{
dbContext = new BasDbContext();
}
public Dictionary<Type, object> repositories = new Dictionary<Type, object>();
public IBasRepositoryBase<T> Repository<T>() where T : class
{
// 检查仓储类是否已经创建,如果存在将返回一个实例,
// 否则将创建一个新的实例。
if (repositories.Keys.Contains(typeof(T)) == true)
{
return repositories[typeof(T)] as IBasRepositoryBase<T>;
}
IBasRepositoryBase<T> repo = new BasRepositoryBase<T>(dbContext);
repositories.Add(typeof(T), repo);
return repo;
}
public void SaveChanges()
{
dbContext.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
dbContext.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
仓储
IBasRepositoryBase.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Boer.Cloud.Bas.Domain.Repositories
{
public interface IBasRepositoryBase<T> where T : class
{
void OnBeforeInsert(T entity);
void OnAfterInsert(T entity);
void OnBeforeUpdate(T entity);
void OnAfterUpdate(T entity);
void OnBeforeDelete(T entity);
void OnAfterDelete(T entity);
#region 获得实体的列表
List<T> GetAllList();
Task<List<T>> GetAllListAsync();
Task<List<T>> GetAllListAsync(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
IEnumerable<T> GetAll(Expression<Func<T, bool>> predicate = null);
#endregion
#region 获取实体的列表,支持分页
IEnumerable<T> Get(string orderBy, int pageIndex, int pageSize);
IEnumerable<T> Get(Expression<Func<T, bool>> predicate, string orderBy, int pageIndex, int pageSize);
#endregion
#region 获得单个实体
T Single(Expression<Func<T, bool>> predicate);
Task<T> SingleAsync(Expression<Func<T, bool>> predicate);
T FirstOrDefault(Expression<Func<T, bool>> predicate);
Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate);
#endregion
#region 插入
T Insert(T entity);
Task<T> InsertAsync(T entity);
#endregion
#region 更新
T Update(T entity);
Task<T> UpdateAsync(T entity);
#endregion
#region 删除
void Delete(T entity);
Task DeleteAsync(T entity);
void Delete(Expression<Func<T, bool>> predicate);
Task DeleteAsync(Expression<Func<T, bool>> predicate);
#endregion
#region 其他
int Count();
Task<int> CountAsync();
int Count(Expression<Func<T, bool>> predicate);
Task<int> CountAsync(Expression<Func<T, bool>> predicate);
long LongCount();
Task<long> LongCountAsync();
long LongCount(Expression<Func<T, bool>> predicate);
Task<long> LongCountAsync(Expression<Func<T, bool>> predicate);
#endregion
}
}
BasRepositoryBase.cs
using Boer.Cloud.Bas.Domain.Repositories;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Boer.Cloud.Bas.EntityFramework.Repositories
{
public class BasRepositoryBase<T> : IBasRepositoryBase<T> where T : class
{
private BasDbContext dbContext = null;
public virtual DbSet<T> Table { get { return dbContext.Set<T>(); } }
public BasRepositoryBase(BasDbContext _dbContext)
{
dbContext = _dbContext;
}
public virtual void OnBeforeInsert(T entity){ }
public virtual void OnAfterInsert(T entity) { }
public virtual void OnBeforeUpdate(T entity) { }
public virtual void OnAfterUpdate(T entity) { }
public virtual void OnBeforeDelete(T entity) { }
public virtual void OnAfterDelete(T entity) { }
#region 获得实体的列表
public IQueryable<T> GetAll()
{
return Table;
}
public List<T> GetAllList()
{
return GetAll().ToList();
}
public async Task<List<T>> GetAllListAsync()
{
return await GetAll().ToListAsync();
}
public async Task<List<T>> GetAllListAsync(Expression<Func<T, bool>> predicate)
{
return await GetAll().Where(predicate).ToListAsync();
}
public IEnumerable<T> GetAll(Expression<Func<T, bool>> predicate = null)
{
if (predicate != null)
{
return Table.Where(predicate);
}
return Table.AsEnumerable();
}
#endregion
#region 获取实体的列表,支持分页
public IEnumerable<T> Get(string orderBy, int pageIndex, int pageSize)
{
return
GetAll()
.OrderBy(orderBy)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.AsEnumerable();
}
public IEnumerable<T> Get(Expression<Func<T, bool>> predicate,
string orderBy, int pageIndex, int pageSize)
{
return
GetAll().Where(predicate)
.OrderBy(orderBy)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.AsEnumerable();
}
#endregion
#region 获得单个实体
public T Single(Expression<Func<T, bool>> predicate)
{
return GetAll().Single(predicate);
}
public async Task<T> SingleAsync(Expression<Func<T, bool>> predicate)
{
return await GetAll().SingleAsync(predicate);
}
public T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return GetAll().FirstOrDefault(predicate);
}
public async Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate)
{
return await GetAll().FirstOrDefaultAsync(predicate);
}
#endregion
#region 插入
public T Insert(T entity)
{
return Table.Add(entity);
}
public Task<T> InsertAsync(T entity)
{
return Task.FromResult(Table.Add(entity));
}
#endregion
#region 更新
public T Update(T entity)
{
AttachIfNot(entity);
dbContext.Entry(entity).State = EntityState.Modified;
return entity;
}
public Task<T> UpdateAsync(T entity)
{
AttachIfNot(entity);
dbContext.Entry(entity).State = EntityState.Modified;
return Task.FromResult(entity);
}
#endregion
#region 删除
public void Delete(T entity)
{
AttachIfNot(entity);
Table.Remove(entity);
}
public Task DeleteAsync(T entity)
{
Delete(entity);
return Task.FromResult(0);
}
public void Delete(Expression<Func<T, bool>> predicate)
{
foreach (var entity in GetAll().Where(predicate).ToList())
{
Delete(entity);
}
}
public async Task DeleteAsync(Expression<Func<T, bool>> predicate)
{
Delete(predicate);
}
#endregion
#region 其他
public int Count()
{
return GetAll().Count();
}
public async Task<int> CountAsync()
{
return await GetAll().CountAsync();
}
public int Count(Expression<Func<T, bool>> predicate)
{
return GetAll().Where(predicate).Count();
}
public async Task<int> CountAsync(Expression<Func<T, bool>> predicate)
{
return await GetAll().Where(predicate).CountAsync();
}
public long LongCount()
{
return GetAll().LongCount();
}
public async Task<long> LongCountAsync()
{
return await GetAll().LongCountAsync();
}
public long LongCount(Expression<Func<T, bool>> predicate)
{
return GetAll().Where(predicate).LongCount();
}
public async Task<long> LongCountAsync(Expression<Func<T, bool>> predicate)
{
return await GetAll().Where(predicate).LongCountAsync();
}
#endregion
protected virtual void AttachIfNot(T entity)
{
if (!Table.Local.Contains(entity))
{
Table.Attach(entity);
}
}
}
}
创建DbContext
提到DbContext,对于经常使用DbFirst模式的开发者来说已经再熟悉不过了,EntityFramework全靠这员大将。它的作用是代表与数据库连接的会话,提供了查询、状态跟踪、保存等功能。
还有一个重要的对象是DbSet,对实体类型提供了集合操作,比如Add、Attach、Remove。继承了DbQuery,所以可以提供查询功能。
BasDbContext.cs
using Boer.Cloud.Bas.Domain.Entities;
using Boer.Cloud.Bas.EntityFramework.Mapping;
using Boer.Cloud.Core.Helper;
using System;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Diagnostics;
namespace Boer.Cloud.Bas.EntityFramework
{
public class BasDbContext : DbContext
{
public BasDbContext()
: base("name=DefaultDBConnection")
{
Database.SetInitializer<BasDbContext>(null);
this.Database.Log = new Action<string>(q => Debug.WriteLine(q));
}
#region Property
public virtual IDbSet<AreaCategory> AreaCategories { get; set; }
public virtual IDbSet<DictCategory> DictCategories { get; set; }
public virtual IDbSet<Dict> Dicts { get; set; }
#endregion
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// 设置禁用一对多级联删除
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
// 设置Schema
modelBuilder.HasDefaultSchema(Config.GetValue("DefaultSchema", "BOER"));
#region BasMapping
modelBuilder.Configurations.Add(new AreaCategoryMap());
modelBuilder.Configurations.Add(new DictCategoryMap());
modelBuilder.Configurations.Add(new DictMap());
#endregion
}
}
}
应用服务
IAreaCategoryAppService.cs
using Boer.Cloud.Bas.Application.AreaCategoryMgr.Dtos;
using Boer.Cloud.Core.Dto;
using System.Threading.Tasks;
namespace Boer.Cloud.Bas.Application.AreaCategoryMgr
{
public interface IAreaCategoryAppService
{
Task<JsonMessage> Create(CreateAreaCategoryInput model);
Task<JsonMessage> Update(UpdateAreaCategoryInput model);
Task<JsonMessage> Delete(DeleteAreaCategoryInput model);
Task<JsonMessage> GetInfo(GetAreaCategoryInfoInput model);
JsonMessage GetAll(GetAllAreaCategoryInput model);
}
}
AreaCategoryAppService.cs
using AutoMapper;
using Boer.Cloud.Bas.Application.AreaCategoryMgr.Dtos;
using Boer.Cloud.Bas.Domain.Entities;
using Boer.Cloud.Bas.Domain.Policies;
using Boer.Cloud.Bas.Domain.UnitOfWork;
using Boer.Cloud.Core.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Boer.Cloud.Bas.Application.AreaCategoryMgr
{
public class AreaCategoryAppService : IAreaCategoryAppService
{
private readonly IUnitOfWork _uow = null;
private readonly IBasPolicy _policy = null;
public AreaCategoryAppService(IUnitOfWork uow, IBasPolicy policy)
{
this._uow = uow;
this._policy = policy;
}
public async Task<JsonMessage> Create(CreateAreaCategoryInput model)
{
var entity = Mapper.Map<CreateAreaCategoryInput, AreaCategory>(model);
entity.AreaId = Guid.NewGuid().ToString("N").ToUpper();
await _uow.Repository<AreaCategory>().InsertAsync(entity);
_uow.SaveChanges();
return _policy.GetErrorMsgByErrCode(0);
}
public async Task<JsonMessage> Update(UpdateAreaCategoryInput model)
{
if (string.IsNullOrEmpty(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601003);
var entity = Mapper.Map<UpdateAreaCategoryInput, AreaCategory>(model);
await _uow.Repository<AreaCategory>().UpdateAsync(entity);
_uow.SaveChanges();
return _policy.GetErrorMsgByErrCode(0);
}
public async Task<JsonMessage> Delete(DeleteAreaCategoryInput model)
{
if (string.IsNullOrEmpty(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601003);
if (_policy.IsExistsByParentAreaId(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601004);
if (_policy.IsNullByAreaCategories(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601002);
await _uow.Repository<AreaCategory>().DeleteAsync(b => b.AreaId == model.AreaId);
_uow.SaveChanges();
return _policy.GetErrorMsgByErrCode(0);
}
public async Task<JsonMessage> GetInfo(GetAreaCategoryInfoInput model)
{
if (string.IsNullOrEmpty(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601003);
if (_policy.IsNullByAreaCategories(model.AreaId))
return _policy.GetErrorMsgByErrCode(20601002);
var entity = await _uow.Repository<AreaCategory>().SingleAsync(b => b.AreaId == model.AreaId);
JsonMessage jsonMsg = _policy.GetErrorMsgByErrCode(0);
jsonMsg.Result = Mapper.Map<AreaCategory, AreaCategoryOutput>(entity);
return jsonMsg;
}
public JsonMessage GetAll(GetAllAreaCategoryInput model)
{
var entity = _uow.Repository<AreaCategory>().GetAll().OrderBy(item => item.AreaCode).ToList();
JsonMessage jsonMsg = _policy.GetErrorMsgByErrCode(0);
jsonMsg.Result = Mapper.Map<List<AreaCategoryOutput>>(entity);
return jsonMsg;
}
}
}