繁体   English   中英

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

[英]How to use Store Procedure and Complex types using Repository Pattern in EF?

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

在什么情况下我们实际上应该采用存储库模式?

提前致谢

我认为你已经错过了为什么人们在EF已经通过ObjectSet / DbSet实现存储库模式时实现存储库模式的原因?

流行的答案是因为许多教程建议你使用它而不需要理由。 有正当理由不在 ObjectSet / DbSet 上使用 Repository层。 但是,我会指出一些原因,为什么它更可取。

默认过滤器在现实生活中,您需要默认过滤器的情况很多。 例如,不销售已停产的产品。 如果直接公开Products ObjectSet / DbSet,如果有人忘记应用默认过滤器,则会出现问题。 它还避免了逻辑的重复。 您也可以稍后修改默认筛选器,而不会破坏问题。

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

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

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

只读实体在许多情况下,某些其他应用程序负责创建,删除和更新实体,而您的应用程序仅显示实体。 但在这种情况下,ObjectSet / DbSet公开了不受支持的功能。 在这种情况下,另一个NoTracking是使用NoTracking选项来减少实体实现时间。

切换数据访问而不暴露实现有时LINQ是不够的。 在这里,您可以使用原始SQL或SP。 拥有存储库将避免在EF公开的功能不足时暴露不同的查询/更新方法。

使用现有数据库当您无法创建EF能够处理的数据库时。 现有表可能具有Sql VariantXML列。 将条目复制到另一个表以及为了保持数据库的完整性而需要处理的无数其他情况。

这些技术可能不是防弹,但如果情况需要,它会派上用场。 我建议不要直接跳到存储库,你最好考虑添加另一个抽象层来实现所需的功能。

存储库模式对于将数据存储机制与应用程序分离很重要。 通过这样做,您可以更轻松地在以后进行单元测试或替换数据结构。 请阅读我的博客文章,了解我为何/为何在此处执行此操作: http//blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

我个人从不再使用存储过程,因为在大多数情况下我并不真正看到它们,但是为了用我的存储库模式实现这个,我建议你创建一个新的RepositoryDataSource来映射到你的存储过程,然后调用通过EF或旧学校SQL存储的进程。 我建议在更新或保存时抛出某种异常。

==编辑(回答'为什么2层'的问题)==

我选择使用两层的原因是因为在我看来,存储库既与你如何获取数据(数据源层)以及如何呈现图层有关(在我的实现中,可能名称很糟糕的存储库) 。 通过将实现分成两半,无论如何都可以保持相同。 相反,如果你想改变你如何做到这一点,同时保持松散地耦合到什么。

例如,您可能希望将EF数据源交换为内存版本。 这不一定会改变数据呈现给应用程序的方式。

另一方面,您可能希望缓存数据或预先记录有关写入数据存储区性能的一些信息。 为什么在封面下使用实际的存储机制至关重要?

就个人而言,我发现在这个特定的地方分裂,使解决方案更灵活。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM