use*_*901 9 c# entity-framework repository repository-pattern
在实体框架中处理存储库模式时,我们如何使用存储过程和复杂类型?有人可以给出一个简单的例子.
在什么情况下我们实际上应该采用存储库模式?
提前致谢
Era*_*nga 14
我认为你已经错过了为什么人们在EF已经通过ObjectSet/DbSet实现存储库模式时实现存储库模式的原因?
流行的答案是因为许多教程建议你使用它而不需要理由.有正当理由不在 ObjectSet/DbSet 上使用 Repository层.但是,我会指出一些原因,为什么它更可取.
默认过滤器 在现实生活中,您需要默认过滤器的情况很多.例如,不销售已停产的产品.如果直接公开Products ObjectSet/DbSet,如果有人忘记应用默认过滤器,则会出现问题.它还避免了逻辑的重复.您也可以稍后修改默认筛选器,而不会破坏问题.
public IQueriable<Product> GetAll()
{
return context.Products.Where(p => !p.IsDiscontinued);
}
Run Code Online (Sandbox Code Playgroud)
软删除
许多应用程序使用软删除,您可以保留列,例如IsDeleted不实际删除行.现在ObjectSet/DbSet有一个Delete方法但是一旦你调用这个方法,它就会null为可以为空的FK属性赋值.你可能不想要这个.
public void Delete(Product product)
{
// can apply any other logic here
product.IsDeleted = true;
}
Run Code Online (Sandbox Code Playgroud)
只读实体
在许多情况下,某些其他应用程序负责创建,删除和更新实体,而您的应用程序仅显示实体.但在这种情况下,ObjectSet/DbSet公开了不受支持的功能.在这种情况下,另一个好处是使用NoTracking选项来减少实体实现时间.
切换数据访问而不暴露实现有时LINQ是不够的.在这里,您可以使用原始SQL或SP.拥有存储库将避免在EF公开的功能不足时暴露不同的查询/更新方法.
使用现有数据库
当您无法创建EF能够处理的数据库时.现有的表可以有Sql Variant,XML列.将条目复制到另一个表以及为了保持数据库的完整性而需要处理的无数其他情况.
这些技术可能不是防弹的,但如果情况需要它会派上用场.我建议不要直接跳到存储库,你最好考虑添加另一个抽象层来实现所需的功能.
存储库模式对于将数据存储机制与应用程序解耦非常重要。通过这样做,您可以更轻松地在以后进行单元测试或替换数据结构。阅读我的博客文章,了解我如何/为何这样做:http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html
就我个人而言,我不再使用存储过程,因为在大多数情况下我并不真正认为需要它们,但是为了使用我的存储库模式实现这一点,我建议您创建一个新的 RepositoryDataSource 来映射到您的存储过程,然后调用通过 EF 或老式 SQL 存储过程。我建议在更新或保存时抛出某种异常。
==编辑(回答“为什么有两层”的问题)==
我选择采用两层的原因是因为在我看来,存储库既与如何获取数据(数据源层)又如何呈现该层有关(在我的实现中,可能是命名不当的存储库) 。通过将实现一分为二,无论做什么,如何实现都可以保持不变。相反,如果您想改变方式,同时保持与内容的松散耦合。
例如,您可能希望将 EF 数据源替换为内存版本。这不一定会改变数据呈现给应用程序的方式。
另一方面,您可能希望缓存数据或预先记录有关数据存储写入性能的一些信息。为什么幕后使用的实际存储机制很重要?
就我个人而言,我发现这个特定位置的拆分使解决方案更加灵活。
| 归档时间: |
|
| 查看次数: |
1667 次 |
| 最近记录: |