C# · 12月 27, 2021

c# – 如何在EF中使用存储库模式使用存储过程和复杂类型?

在实体框架中处理Repository模式时,我们如何使用存储过程和复杂类型?有人可以给出一个简单的例子.

还应该在什么情况下我们实际去找一个Repository模式?

提前致谢

解决方法 我想你已经错过了一点,为什么人们通过ObjectSet / DbSet实现存储库模式时,实现存储库模式?

热门的回答是因为许多教程建议您使用它,而无需证明理由.有没有在ObjectSet / DbSet上使用Repository层的有效理由.不过,我会指出一些理由,为什么它更可取.

默认过滤器
在需要默认过滤器的现实应用中有很多情况.例如停产的产品没有出售.如果直接暴露产品ObjectSet / DbSet,则有人忘记应用默认过滤器会出现问题.它也避免了逻辑的重复.您也可以稍后修改默认过滤器,而不会出现问题.

public IQueriable<Product> GetAll(){ return context.Products.Where(p => !p.IsDiscontinued);}

软删除
许多应用程序使用软删除,您可以在其中保留列,如IsDeleted而不实际删除该行.现在ObjectSet / DbSet有一个Delete方法,但是一旦调用这个方法,它将为可空的FK属性分配空值.你可能不想要这个.

public void Delete(Product product){ // can apply any other logic here product.IsDeleted = true;}

只读实体
有许多其他应用程序负责创建,删除和更新实体的情况很多,您的应用程序只显示实体.但是在这种情况下,ObjectSet / DbSet会显示不支持的功能.在这种情况下,另一个好处就是使用NoTracking选项来减少实体实现时间.

切换数据访问而不暴露实现有些情况下LINQ不足.在这里可以使用原始sql或SP.拥有存储库将避免在EF暴露的功能不足时查询/更新不同的方法.

使用现有数据库
当您没有创造EF能够处理的数据库的奢侈时.现有表可能具有sql Variant,XML列.将条目复制到另一个表以及您需要处理的无数其他情况以保持数据库的完整性.

这些技术可能不是防弹的,但如果情况需要,将会派上用场.我建议的不是直接进入存储库,更好地考虑添加另一个实现所需功能所需的抽象层.