简体   繁体   English

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

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

How can we use store procedures, and complex types while dealing with Repository pattern in Entity Framework?Could anybody please give a simple example. 在实体框架中处理存储库模式时,我们如何使用存储过程和复杂类型?有人可以给出一个简单的例子。

Also in what situation should we actually go for an Repository pattern? 在什么情况下我们实际上应该采用存储库模式?

Thanks in advance 提前致谢

I think you have missed a point as to why people implement repository pattern when EF already implements repository pattern through ObjectSet/DbSet? 我认为你已经错过了为什么人们在EF已经通过ObjectSet / DbSet实现存储库模式时实现存储库模式的原因?

Popular answer would be because many tutorials advice you to use it without justifying reasons. 流行的答案是因为许多教程建议你使用它而不需要理由。 There are valid reasons not to use Repository layer over ObjectSet/DbSet. 有正当理由不在 ObjectSet / DbSet 上使用 Repository层。 However I will point out some reasons as to why it it preferable. 但是,我会指出一些原因,为什么它更可取。

Default filters There are many situations in real life applications where you need a default filter. 默认过滤器在现实生活中,您需要默认过滤器的情况很多。 For example discontinued products are not sold. 例如,不销售已停产的产品。 If you expose the Products ObjectSet/DbSet directly there will be problems if someone forgot to apply the default filter. 如果直接公开Products ObjectSet / DbSet,如果有人忘记应用默认过滤器,则会出现问题。 It also avoids the duplication of the logic. 它还避免了逻辑的重复。 You can also modify the default filter later without breaking issues. 您也可以稍后修改默认筛选器,而不会破坏问题。

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

Soft Deletes Many applications use soft deletes where you keep a column such as IsDeleted without actually removing the row. 软删除许多应用程序使用软删除,您可以保留IsDeleted等列而不实际删除该行。 Now the ObjectSet/DbSet has a Delete method but once you call this method it will assign null values to the nullable FK properties. 现在的对象集/ DbSet有一个Delete方法,但一旦你调用这个方法将分配null值可为空FK属性。 You may not want this. 你可能不想要这个。

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

Read Only Entities There are many situation where some other application is in charge of creating, deleting and updating entities and your application is only displaying the entity. 只读实体在许多情况下,某些其他应用程序负责创建,删除和更新实体,而您的应用程序仅显示实体。 But the ObjectSet/DbSet exposes unsupported functionality in this case. 但在这种情况下,ObjectSet / DbSet公开了不受支持的功能。 Another benifit in this case would be to use NoTracking option to reduce the entity materialization time. 在这种情况下,另一个NoTracking是使用NoTracking选项来减少实体实现时间。

Switch Data Access without exposing implementation There are occasions where LINQ is not sufficient. 切换数据访问而不暴露实现有时LINQ是不够的。 Here you can use raw SQL or SPs. 在这里,您可以使用原始SQL或SP。 Having a repository will avoid exposing different methods of querying/updating when the functionality exposed by EF is not sufficient. 拥有存储库将避免在EF公开的功能不足时暴露不同的查询/更新方法。

Working with Existing Databases When you do not have the luxury of creating the database that EF is capable of handling. 使用现有数据库当您无法创建EF能够处理的数据库时。 Existing table may have Sql Variant , XML columns. 现有表可能具有Sql VariantXML列。 Duplication of entries to another tables and countless other cases that you need to handle to keep the integrity of the database. 将条目复制到另一个表以及为了保持数据库的完整性而需要处理的无数其他情况。

These techniques may not be bullet proof but will come in handy if situation demands it. 这些技术可能不是防弹,但如果情况需要,它会派上用场。 What I would suggest is without jumping straight in to repositories you better think about does adding another abstraction layer necessary to implement the required functionalities. 我建议不要直接跳到存储库,你最好考虑添加另一个抽象层来实现所需的功能。

repository patterns are important to decouple your data storage mechanism from your application. 存储库模式对于将数据存储机制与应用程序分离很重要。 By doing this you make it a lot easier to unit test or replace the data structure at a later date. 通过这样做,您可以更轻松地在以后进行单元测试或替换数据结构。 Read my blogpost around how/why I do this here: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html 请阅读我的博客文章,了解我为何/为何在此处执行此操作: http//blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

Personally I never use stored procedures any more as I don't really see a need for them in most circumstances, however to implement this with my repository pattern i would recommend that you create a new RepositoryDataSource to map to your stored procedure and then call the stored proceedure via EF or old school SQL. 我个人从不再使用存储过程,因为在大多数情况下我并不真正看到它们,但是为了用我的存储库模式实现这个,我建议你创建一个新的RepositoryDataSource来映射到你的存储过程,然后调用通过EF或旧学校SQL存储的进程。 I would recommend throwing an exception of some kind on update or save. 我建议在更新或保存时抛出某种异常。

==EDIT (In response to the question 'why 2 layers')== ==编辑(回答'为什么2层'的问题)==

The reason I've chosen to go for two layers is because in my mind a repository is both to do with how you get the data (the data source layer) and how you present the layer (in my implementation, perhaps badly named repository). 我选择使用两层的原因是因为在我看来,存储库既与你如何获取数据(数据源层)以及如何呈现图层有关(在我的实现中,可能名称很糟糕的存储库) 。 By splitting the implementation in half the how can remain the same regardless of the what. 通过将实现分成两半,无论如何都可以保持相同。 conversely if you want to change the how you can do so while remaining only loosely coupled to the what. 相反,如果你想改变你如何做到这一点,同时保持松散地耦合到什么。

For example you may want to swap your EF data source for an in memory version. 例如,您可能希望将EF数据源交换为内存版本。 This shouldn't necessarily change how the data is presented to the application. 这不一定会改变数据呈现给应用程序的方式。

On the other side you may want to cache your data or prehaps log some information on the performance of writes to the datastore. 另一方面,您可能希望缓存数据或预先记录有关写入数据存储区性能的一些信息。 Why should it matter what actual storage mechanism is used under the covers? 为什么在封面下使用实际的存储机制至关重要?

Personally I've found the split in this particular place to make the solution much more flexible. 就个人而言,我发现在这个特定的地方分裂,使解决方案更灵活。

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

相关问题 将AutoMapper与EF6 DbFirst和存储过程一起使用(复杂类型) - Using AutoMapper with EF6 DbFirst and Stored Procedure (complex types) 如何使用存储库模式将 EF 对象转换为 WCF 模型 - How to transform EF Objects to WCF Models using Repository pattern EF如何使用.include()和使用存储库模式查询更多实体 - EF How to query more entities with .include() and using repository pattern 如何使用存储库模式访问EF中的导航属性 - How to access navigation properties in EF using repository pattern EF 4:如何使用具有存储库模式的MVC正确更新DbContext中的对象 - EF 4: How to properly update object in DbContext using MVC with repository pattern 我可以在.Net中使用不带EF的存储过程吗? - Can I use Store procedure without EF in .Net, If yes then How? 如何使用NHibernate在存储库模式中进行复杂联接? - How to do Complex Joins in Repository pattern using NHibernate? 使用EF或NHibernate的存储库模式中的层次结构 - Hierarchical structure in repository pattern using EF or NHibernate 对于返回不同类型的存储库和EF数据上下文,有什么好的模式? - What is a good pattern for a repository and EF data context that return different types? 如何为 EF 和存储库模式设置项目结构 - How to setup project structure for EF and repository pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM