问题描述
(注意:我的问题与这个问题三个月前,但从未回答过.)
我最近开始使用MVC3 +实体框架,我一直在阅读,最好的做法是使用存储库模式集中对DAL的访问.这也伴随着您要使DAL与域,尤其是视图层分开的解释.但是在我看到的示例中,存储库是(或似乎是)只是返回dal实体,即,在我的情况下,存储库将返回EF实体.
所以我的问题是,如果存储库仅返回DAL实体,那么该存储库有什么好处?这不是添加一层复杂性不会消除两层之间传递DAL实体的问题?如果存储库模式创建了"进入DAL的单点",那么与上下文对象有何不同?如果存储库提供了检索和坚持dal对象的机制,那么与上下文对象有何不同?
另外,我在至少一个地方阅读了工作模式单位集中存储库访问以管理数据上下文对象的位置,但是我不grok,为什么这也很重要.
我98.8%肯定我在这里错过了一些东西,但是从我的阅读中,我没有看到它.当然,我可能只是不阅读正确的来源...:\
推荐答案
实体框架的DbContext基本上类似于存储库(以及工作的工作单位).您不一定必须在简单的方案中抽象出来.
存储库的主要优点是您的领域可以是无知的,并且独立于持久机制.在基于图层的体系结构中,依赖项从UI层通过域(或通常称为业务逻辑层)到数据访问层.这意味着UI取决于BLL,该BLL本身取决于DAL.
在更现代的体系结构(由域驱动的设计和其他面向对象的方法传播)中,域不应具有外向依赖性.这意味着UI,持久机制和其他所有内容都应取决于域,而不是相反.
然后,将通过其在域内的接口表示一个存储库,但在持久模块中在域之外具有具体的实现.这样,域仅取决于抽象接口,而不是具体实现.
基本上是对象取向与架构层面上的程序编程.
另请参见其他推荐答案 我认为"存储库"通常是在" reposotory模式"由书/a>马丁·福勒(Martin Fowler). 一个存储库介导域和数据映射层之间,
像内存域对象集合一样起作用.客户端对象
声明构建查询规格,并将其提交给
存储库以满意.可以添加对象并从
存储库,就像简单的对象集合一样,以及
存储库封装的映射代码将执行
幕后合适的操作. 在表面上,实体框架完成了所有这些工作,可以用作存储库的简单形式.但是,存储库不仅仅是数据层抽象. 根据这本书 domain驱动的设计埃里克·埃文斯(Eric Evans),一个存储库具有这些优势:
策略甚至多个数据源中解脱出来
第一个点大致等同于上面的段落,很容易看到实体框架本身可以轻松完成它.
有些人会争辩说EF也完成了第二点.但是通常使用EF仅将每个数据库表转变为EF实体,然后将其传递给UI.它可能正在抽象数据访问的机制,但几乎没有将幕后关系的关系结构抽象.
在大多数 的简单应用中,这似乎不是重要的一点.但是,随着应用程序的域规则/业务逻辑变得更加复杂,您可能希望成为更面向对象的.数据的关系结构包含对业务领域并不重要的,而是数据存储的副作用并不少见.在这种情况下,还不足以抽象持久性机制,也是数据结构本身的性质.仅EF通常不会帮助您做到这一点,但是存储库层会.
至于第三个优势,EF将不做任何事情(从DDD角度)来提供帮助.通常,DDD不仅使用存储库来抽象数据持久性的机理,而且还提供围绕如何访问某些数据的约束:
我们也不需要查询持续的对象的查询访问 方便遍历遍历.例如,一个人的地址 可以从人对象请求.最重要的 除非通过 遍历根.
换句话说,您不会因为数据库中有一个地址表而没有"地址纠正".如果您的设计选择以这种方式管理如何访问地址对象,则您将在此处定义和执行设计选择.
此外,DDD存储库通常是封装与域数据集有关的某些业务概念的地方.订单重点可能具有一种称为"未符合"的方法,该方法返回特定的订单子集.或客户存储库可能包含首选的bypostalcode方法.
实体框架的dataContext类别没有添加的存储库抽象层,无法很好地适合此功能.它们对于DDD所谓的规范确实很好地工作,可以简单地发送到一个简单的方法,该方法将对表达式评估数据并返回匹配.
至于第四个优势,虽然我敢肯定有某些策略可能会替换DataContext,然后将其包装在存储库中,使其变得简单.
关于"工作单位",这是DDD书必须说的:
将事务控制留给客户端.,尽管存储库将插入并从数据库中删除,但通常不会 提交任何东西.节省后,很容易提交,例如 但是客户大概有上下文可以正确启动和 承担工作单位.如果是 存储库保持开头.
其他推荐答案
您是对的,在这些简单的情况下,存储库只是DAO的另一个名称,它仅带来一个值:您可以将EF切换到另一个数据访问技术的事实.今天,您正在使用MSSQL,明天您需要一个云存储.或使用微ORM代替EF或从MSSQL切换到mySQL.
在所有这些情况下,使用存储库都是很好的,因为该应用程序的其余部分不在乎您现在正在使用的存储.
还有一个有限的情况,您可以从多个来源获得信息(DB +文件系统),回购将充当立面,但仍然是DAO的另一个名称.
一个"真实"存储库仅在处理域/业务对象时才有效
问题描述
(Note: My question has very similar concerns as the person who asked this question three months ago, but it was never answered.)
I recently started working with MVC3 + Entity Framework and I keep reading that the best practice is to use the repository pattern to centralize access to the DAL. This is also accompanied with explanations that you want to keep the DAL separate from the domain and especially the view layer. But in the examples I've seen the repository is (or appears to be) simply returning DAL entities, i.e. in my case the repository would return EF entities.
So my question is, what good is the repository if it only returns DAL entities? Doesn't this add a layer of complexity that doesn't eliminate the problem of passing DAL entities around between layers? If the repository pattern creates a "single point of entry into the DAL", how is that different from the context object? If the repository provides a mechanism to retrieve and persist DAL objects, how is that different from the context object?
Also, I read in at least one place that the Unit of Work pattern centralizes repository access in order to manage the data context object(s), but I don't grok why this is important either.
I'm 98.8% sure I'm missing something here, but from my readings I didn't see it. Of course I may just not be reading the right sources... :\
推荐答案
Entity Framework's DbContext basically resembles a Repository (and a Unit of Work as well). You don't necessarily have to abstract it away in simple scenarios.
The main advantage of the repository is that your domain can be ignorant and independent of the persistence mechanism. In a layer based architecture, the dependencies point from the UI layer down through the domain (or usually called business logic layer) to the data access layer. This means the UI depends on the BLL, which itself depends on the DAL.
In a more modern architecture (as propagated by domain-driven design and other object-oriented approaches) the domain should have no outward-pointing dependencies. This means the UI, the persistence mechanism and everything else should depend on the domain, and not the other way around.
A repository will then be represented through its interface inside the domain but have its concrete implementation outside the domain, in the persistence module. This way the domain depends only on the abstract interface, not the concrete implementation.
That basically is object-orientation versus procedural programming on an architectural level.
See also the Ports and Adapters a.k.a. Hexagonal Architecture.
Another advantage of the repository is that you can create similar access mechanisms to various data sources. Not only to databases but to cloud-based stores, external APIs, third-party applications, etc.
其他推荐答案
I think the term "repository" is commonly thought of in the way the "repository pattern" is described by the book Patterns of Enterprise Application Architecture by Martin Fowler.
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.
On the surface, Entity Framework accomplishes all of this, and can be used as a simple form of a repository. However, there can be more to a repository than simply a data layer abstraction.
According to the book Domain Driven Design by Eric Evans, a repository has these advantages:
- They present clients with a simple model for obtaining persistence objects and managing their life cycle
- They decouple application and domain design from persistence technology, multiple database strategies, or even multiple data sources
- They communicate design decisions about object access
- They allow easy substitution of a dummy implementation, for unit testing (typically using an in-memory collection).
The first point roughly equates to the paragraph above, and it's easy to see that Entity Framework itself easily accomplishes it.
Some would argue that EF accomplishes the second point as well. But commonly EF is used simply to turn each database table into an EF entity, and pass it through to UI. It may be abstracting the mechanism of data access, but it's hardly abstracting away the relational data structure behind the scenes.
In simpler applications that mostly data oriented, this might not seem to be an important point. But as the applications' domain rules / business logic become more complex, you may want to be more object oriented. It's not uncommon that the relational structure of the data contains idiosyncrasies that aren't important to the business domain, but are side-effects of the data storage. In such cases, it's not enough to abstract the persistence mechanism but also the nature of the data structure itself. EF alone generally won't help you do that, but a repository layer will.
As for the third advantage, EF will do nothing (from a DDD perspective) to help. Typically DDD uses the repository not just to abstract the mechanism of data persistence, but also to provide constraints around how certain data can be accessed:
We also need no query access for persistent objects that are more convenient to find by traversal. For example, the address of a person could be requested from the Person object. And most important, any object internal to an AGGREGATE is prohibited from access except by traversal from the root.
In other words, you would not have an 'AddressRepository' just because you have an Address table in your database. If your design chooses to manage how the Address objects are accessed in this way, the PersonRepository is where you would define and enforce the design choice.
Also, a DDD repository would typically be where certain business concepts relating to sets of domain data are encapsulated. An OrderRepository may have a method called OutstandingOrdersForAccount which returns a specific subset of Orders. Or a Customer repository may contain a PreferredCustomerByPostalCode method.
Entity Framework's DataContext classes don't lend themselves well to such functionality without the added repository abstraction layer. They do work well for what DDD calls Specifications, which can be simple boolean expressions sent in to a simple method that will evaluate the data against the expression and return a match.
As for the fourth advantage, while I'm sure there are certain strategies that might let one substitute for the datacontext, wrapping it in a repository makes it dead simple.
Regarding 'Unit of Work', here's what the DDD book has to say:
Leave transaction control to the client. Although the REPOSITORY will insert into and delete from the database, it will ordinarily not commit anything. It is tempting to commit after saving, for example, but the client presumably has the context to correctly initiate and commit units of work. Transaction management will be simpler if the REPOSITORY keeps its hands off.
其他推荐答案
You're right,in those simple cases the repository is just another name for a DAO and it brings only one value: the fact that you can switch EF to another data access technique. Today you're using MSSQL, tomorrow you'll want a cloud storage. OR using a micro orm instead of EF or switching from MSSQL to MySql.
In all those cases it's good that you use a repository, as the rest of the app won't care about what storage you're using now.
There's also the limited case where you get information from multiple sources (db + file system), a repo will act as the facade, but it's still a another name for a DAO.
A 'real' repository is valid only when you're dealing with domain/business objects, for data centric apps which won't change storage, the ORM alone is enough.