0
我在一个项目中工作,我有一个通用服务和存储库层。我使用Automapper将DTO映射到实体模型。一个实体可以有一个或多个DTO。我的问题是,如何告诉我的通用存储库类,哪个DTO应该返回到服务层?具有多个DTO到一个实体的通用存储库(Automapper)
实体
[Table("Entity")]
public class Entity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
[Required]
public string name { get; set; }
[Required]
public string surname { get; set; }
}
的DTO
public class Contract
{
}
[DataContract]
public class EntityContract: Contract
{
[Required]
[DataMember]
public string name { get; set; }
[Required]
[DataMember]
public string surname { get; set; }
}
[DataContract]
public class EntityPassportContract: Contract
{
[Required]
[DataMember]
public string name { get; set; }
[Required]
[DataMember]
public string surname { get; set; }
[Required]
[DataMember]
public string passport { get; set; }
}
通用仓库
public interface IGenericRepository<E, DTO>
where E : class
where DTO: class
{
List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null);
}
戈neric仓库实现
public abstract class GenericRepository<C, E, DTO> : IGenericRepository<T, DTO>
where E : class
where DTO: class
where C : IdentityDbContext<User>, new()
{
//...
public virtual List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null)
{
//...transform DTO queries to E queries and Get IQueriable<E> entity from database
DTO dtoEntity=entity.ProjectTo<DTO>();
return dtoEntity;
}
}
通用服务
public interface IService<E, DTO> : IService
where T: class
where DTO: class
{
List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null);
}
通用服务实现
public abstract class Service<E, DTO> : IService<T, DTO>
where E: class
where DTO: class
{
protected IGenericRepository<E, DTO> repository;
public Service(IGenericRepository<E, DTO> repository,)
{
this.repository = repository;
}
public virtual List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null)
{
return repository.findBy(query, orderBy, whereIn, page, sizePage).ToList();
}
}
实体存储库和服务
public interface IEntityRepository : IGenericRepository<Entity, Contract>
{
}
public class EntityRepository : GenericRepository<EntitiesDB, Entity, Contract>, IEntityRepository
{
public EntityRepository(IMapper mapper):base(mapper){ }
}
//Service
public interface IEntityService : IService<Entity, Contract>
{
}
public class EntityService : Service<Entity, Contract>, IEntityService
{
private IEntityRepository repo;
public EntityService(IEntityRepository repo) : base(repo)
{
this.repo = repo;
}
}
控制器 我要调用的方法findBy在通用服务,并选择其中DTO是要回来。合同类是我测试的一部分,但它不起作用。 我是否必须使用反射可能会传递服务中的每种方法我想要的DTO的类型?
[RoutePrefix("api/entity")]
public class EntityController : ApiController
{
public EntityController(IEntityService entityService)
: base(entityService)
{
}
[Route("getEntityByFilter", Name = "getEntityByFilter")]
[HttpGet]
public async Task<IHttpActionResult> getEntityContract(string filter)
{
EntityContract entityContract=entityService.findBy(**Parameters**); //Need to call lambda expressions here so i think i need somehow the type.
return Ok(entityContract);
}
[Route("getEntityByFilter2", Name = "getEntityByFilter2")]
[HttpGet]
public async Task<IHttpActionResult> getEntityPassportContract(string filter)
{
EntityPassportContract entityPassportContract=entityService.findBy(**Parameters**); //Need to call lambda expressions here so i think i need somehow the type.
return Ok(entityPassportContract);
}
}
非常感谢!我希望这个问题也能帮助其他人!
周末愉快!
Luciano
现在你面临着试图以通用方式制造“一切”的后果。编程是关于上下文的,你首先分离一切,然后当你看到一些通用模式时,你将使用通用的方法。 – Fabio
感谢@Fabio为您解答。我已经有了一些特定的存储库和服务来做一些特定的事情。我想用通用的做一些简单的CRUD操作。如果我为每个存储库构建一个findBy,我将为每个实体使用完全相同的代码,但具有不同的返回类型(不同的合同)。我想避免这种情况。谢谢! –
我不认为如果你想在一个方法'getEntityContract'中做一个这样做的方法,那么这个方法应该知道返回的类型,无论是作为参数还是头部(无论你感觉如何),然后使用反射来执行使用通用执行的findBy。 也请改变URL名称,就像每个REST一样,URL应该看起来像“api/entities/byfilter”而不是“api/entity/getEntityByFilter” 如果你找到其他方法,请评论。 – Prince