我正在编写一个控制台应用程序,它可以从存储过程记录集中执行大量数据检索。对于我正在使用的每个记录集类型,我有一个使用EF和自定义复杂类型的存储库来检索数据:
public interface IBalanceSheetRepository
{
IEnumerable<BalanceSheetRecordDTO> GetBalanceSheetRecords();
}
public class BalanceSheetRepository : IBalanceSheetRepository
{
DBContext _context;
...
public IEnumerable<BalanceSheetRecordDTO> GetBalanceSheetRecords()
{
ObjectResult<BalanceSheetRecord> results = _context.GetBalanceSheet();
return results.Select(CreateBalanceSheetDTOFromDAO);
}
private static BalanceSheetRecordDTO CreateBalanceSheetDTOFromDAO(BalanceSheetRecord dao)
{
return new BalanceSheetRecordDTO { ... };
}
}
这里,BalanceSheetRecord
是我在设计器中创建的复杂数据类型。我创建了一个DTO以避免耦合,因为BLL不应该知道BalanceSheetRecord
类型。
这是我的问题:由于DTO类型用于存储库接口的方法签名,并且因为我的BLL最终将使用存储库&amp;返回DTO的集合,这似乎是一个贯穿各领域的关注点。因此,我让DTO与repo接口一起生活在一个单独的“Infrastructure”组件中。这是我努力实现的良好做法,还是我在某个地方转错了?
另外:在我的存储库中新建数据上下文是不好的做法?当两个组件都属于DAL时,是否有一定量的耦合?我想使用DI,但是对于交换TestBalanceSheetRepository
的repo的DBContext实现似乎更有用。
答案 0 :(得分:6)
我更喜欢从我的存储库返回实际实体。这样,当您需要协调服务层中不同实体之间的复杂交互时,就不会来回转换到DTO。然后,当将数据返回到应用程序层时,服务层将实体投影到DTO中。
我知道有些纯粹主义者说层之间的所有互动都应该用DTO来完成,但我发现这是不切实际的。无论如何,服务层最终会耦合到实体,所以它不像你正在添加耦合。
它还限制了DTO到实体到服务层的投影/展平。对我来说这是一个加分,因为这些活动增加了复杂性并降低了性能。
您的数据环境是您的工作单位。 “每个存储库的一个工作单元”的想法是一种反模式。工作单元应由服务层确定范围,这可能涉及来自1-many存储库的1-many实体。如果每个存储库具有不同的工作单元,则您将无法轻松地使服务层调用保持一致的事务。