public interface IRepository<TEntity>
{
TEntity FindById(Guid id);
void Add(TEntity entity);
void Remove(TEntity entity);
}
这是一个简单的通用存储库。如果我有一个Product
实体,则此存储库可以插入,更新和删除(使用实体框架)。
但我创建了基于报告的类型。
例如:
每个托运人发送的订单数量。
public class OrdersWithShipper {
public string ShipperName{get;set;}
public string NumberOfOrder{get;set;}
}
等等。
所以我应该为许多相关的表创建复杂的查询。但查询结果对象未使用存储库TEntity
实体类型表示。
我有很多这样的报告类型。我怎么解决这个问题?
答案 0 :(得分:2)
这个问题的直接问题是:
所以我应该为许多相关的表创建复杂的查询。但 查询结果对象未使用存储库TEntity实体表示 类型。
我会说你不应该在这里使用存储库模式,因为它打破了它。例如,存储库应该处理返回和管理它所针对的域对象,以支持域行为,而不是随机查询对象以支持报告行为。
如果不坚持使用相同的类型,您几乎肯定不知道在哪里绘制线条,例如查询对象与哪个存储库等等...所以你应该保持简单。
例如,将不同的模式应用于报告(或查询)。也许为您的视图模型创建类(View Model Builders?),它们直接依赖于IDbSet<T>
来查询逻辑。
或者,进一步抽象并具有查询处理程序/查询提供程序模式(这将是我的选择)。
看看这里的答案:
Well designed query commands and/or specifications
我使用了类似的模式并取得了巨大的成功。
答案 1 :(得分:0)
我这样做的技巧是将Repository
包装在可以接受ViewModel的Service
类中。换句话说,我的控制器正在使用我制作的服务类而不是直接使用存储库。
另外,我使用AutoMapper
库来映射
以下示例:
public class OrderWithShipperProductService()
{
public ProductRepository { get; set; }
public OrderWithShipperProductService(ProductRepository repo)
{
this.ProductRepository = repo;
}
public void AddOrderWithShipperProduct(OrderWithShipperProduct model)
{
var entity = Mapper.Map<TEntity>(model);
ProductRepository.Add(entity);
}
}
您可能需要学习Automapper here。 但是如果需要,您也可以在构造函数中自己映射它。 或者您也可以创建自己的映射函数。