特别是 nHibernate (3.0+) 和 EF 支持 LINQ,因此您的代码创建了一个简单的 IRepository 接口,该接口接受 Expression<Func<TItemType,bool>> 并避免拥有具有 GetPersonByID、getPersonByName 等的存储库。虽然这可能会妨碍您交换 ORM I认为您不会使用不支持 LINQ 的 ORM。
这个接口可能看起来像这样(这不是一个完整的实现!这只是一个演示,真正的接口需要更好的改进!这只是我现在已经模拟了一些东西!这可能还需要实现 IDisposable 等):
interface IRepository<TPersistant>
{
void Save(TPersistant item);
void Delete(TPersistant item);
TPersistant Find(Expression<Func<TPersistant,bool>> predicate);
// maybe findOne or findMany
// maybe something like this
IQueryable<TPersistant> Query();
/* Other stuff like updating, transactions, commiting, etc.*/
}
不过,我想提一下人们在抽象 DAL 时会忽略的一些事情。 这个o/c是我的全部意见。
虽然抽象可以帮助您在未来“交换” DAL,但如果您从中获得任何好处,我会认真思考,除了创建符合“最佳实践”和“人们说你应该做的”的软件,等等另一只手朝自己的脚开枪。
当您完全抽象 DAL 时,您可能会失去其他 ORM 特定的特性,这些特性实际上使一个 ORM 比另一个更好,甚至为了抽象而失去未来的性能优化。 i/e nHibernate 中的未来查询(imo 是一个巨大的功能),如果将其抽象出来,您基本上会丢失。由于无法使用 Fetch (nHibernate) 或 Include (EF),您可能还会失去惰性初始化优化(选择 N+1 问题)。甚至像 enum 支持这样的小东西(我相信 EF STILL 不支持)。
我还想补充一点,许多开发人员为了未来的变化而创建抽象,而实际上这些变化几乎从未发生过。
所以虽然我不说不要抽象 DAL,因为它有 很多 优点,例如单元测试、解耦等(尽管您总是可以创建一个有助于单元测试的耦合到 dal 存储库),如果值得为一些实际上使 nhibernate/EF 比其他。