How can I query cross tables with Repository Pattern? - asp.net-mvc

In my asp.net mvc 3 application, I'm using the repository pattern.
I have 3 entities, Company, Country, City. Each of them has their own repository. Company entity has FoundedCountry and FoundedCity foreign keys.
Now in a view, I want to show the company details. In this view I want to view Company details as well as, FoundedCountry name and FoundedCity name. In my opinion I have to handle this with a kind of JOIN query. But I'm stuck at how to achieve this in repository pattern. How can I handle this JOIN in repository pattern?
Thank you.

The repository should have a task-based interface. This means that ORM's, joins etc are inside the repository. The app just sees an interface whtch returns an object that it can use.
This means you don't create a repository around a table (it pretty much defeats the purpose). In your scenario I suggest you have (at least) 2 repositories: one will handle everything related to updating the model and the other will serve only reads (queries).
This means the query repository will return only the data you want (it basically returns view model bits). Of course, the actual tables and joins are an implementation detail of the repository.

Don't construct your repository pattern in a way that is preventing joins! This usually means to use the same ORM context (DataContext/ObjectContext) for all instances associated with the current HTTP request.
I consider it to be an anti-pattern to have a generic IRepository because database access is rarely constrained to a single type of entity at the same time.
You could consider the DataContext/ObjectContext to be a repository by itself.
A last advice: If you don't know what a repository abstraction is good for - don't use one.

Related

MVC Repository project setup

I could do with some guidance about how to setup the MVC Repositories with the following scenario.
Below is a sample of the main tables in my project.
Entity
central table used to store common data
can be an Article, Person, Job or Post
an Entity can have 1 or more Tags
Tag
used to store Tag values
Article
stores Article specific information
Person
stores Person specific information
Job
stores Job specific information
Post
stores Post specific information
With the above information in mind, should I be looking to create a Repository
Entity Repository
handles CRUD for an Entity
handles CRUD for Tags
Article
inherits Entity Repository
handles CRUD for a Article
Person
inherits Entity Repository
handles CRUD for a Person
Job
inherits Entity Repository
handles CRUD for a Job
Post
inherits Entity Repository
handles CRUD for a Post
I'm using PetaPoco as my ORM. Is this a suitable approach?
Well, yes and no. Yes, typically, a repository is for one "thing", so each entity would need it's own repository. However, if you're using Entity Framework or another ORM, then implementing the repository pattern on top of it is a hugely bad idea. The entire purpose of an ORM is to give you repositories. In the case of Entity Framework, each DbSet is a repository and your DbContext is your Unit of Work. Adding another layer on top of this will see you merely proxying one method call to another method call on your context, providing no benefit, and increasing the complexity and maintenance costs of your application.
Either just use your ORM directly, or if you want to abstract it, use a service pattern and create endpoints that satisfy specific queries you will need in your application. Depending on the size of your application, you might only need one service, rather than one per type.

Returning Custom Models from LINQ queries, using Repository and Unit of Work with Entity Framework

I have implemented Repository + UnitOfWork pattern in my DAL, I am using Entity Framework (EF) to connect to the DB.
The service layer calls UnitOfWork to get a specific repository, and then interacts with repository methods using EF Entities.
The returned EF Entities from Repository to Service, are then mapped into Models (POCO objects, only properties, no functionality), and then these POCOs are passed to the Controller that called the Service in the first place.
All looks good so far, except when:
I need to use "Joins" in my LINQ queries in my repository, and return a custom object to the service layer.
The problem here is, that I was making sure, my repository only takes in and sends out EF Entities. But if I need to use join, I'll be populating a custom Model object, and will then be passing back Model instead of EF Entity.
To tackle the above problem, I was thinking that I should change my repository such that, it takes IN entities (e.g. for ADD, DELETE, UPDATE), but returns back Models (for select methods etc).
This means, my service layer will be creating Entities from Models, and then passing entities to the Repository, for any ADD, UPDATE, DELETE
And my Repository will be creating Models from Entities when returning results of a select LINQ queries.
Any thoughts if I'll be in a greater problem later if I choose to go with the above design?
If the above design is not a good solution, any other advise?
You're using the wrong repository approach, the anti-pattern. The Repository makes sens only as a decoupling pattern i.e you want tot decouple the Business Layer(BL) from the Persistence Layer(PL).
This means, your Bl (and services) don't know about EF or any other ORM. This means that your repository interface only know about what BL knows,that is the business objects. Your repository should NEVER expose EF, IQueryable or other PL detail.
First of all you need UoW pattern ONLY when updating a model, never just for queries. Then, when you're asking the repository for something, you tell it what you want and the repository will use EF, create queries, joins etc and maps the query results to the POCO the repository returns . So the mapping from EF entities to domain objects is done inside the repository.
Actually, ALL work related to the database via EF (or any other ORM) is done inside the repository. The BL just gets their object in the final form. That's the whole point of the repository.
What you're doing now is wrong, because you are doing repository's work at the BL level, violating the Separation of Concerns principle. The proper use of repository is like I wrote above.
P.S: In case you wonder, the generic repository is an anti pattern, stay away from it. As a side note, a generic repository interface is not the same thing as a generic repository.

Select queries with Repository + Unit of Work Patterns

I have read a lot about Unit of Work and Repositories patterns.
What I have never seen is how would I retrieve data. UoW does not make sense for Select statements.
I will use asp.net MVC with n-tier architecture and this point I never see in any tutorial or article:
Where and how do I call SELECT statements, with/without INNER JOINs, using these patterns?
Calling directly DataContext from Service Layer?
Unit of Work is for updating the model. Indeed for querying you don't need it. When using the Repository Pattern everything db related (selects, joins etc) is part of the repository implementation.
The repository consumer, for example the Controller, takes a dependency on the repository interface (an abstraction) while the concrete repository is injected by the DI Container. The consumer never sees the db or things from it, it just sees the repository methods which should return objects the controller needs and understands (even if you return an ROM entity, the controller doesn't know it's an entity).
One important thing is to understand that the repository interface defines the WHAT not the HOW. The implementation deals with the "how". This means the controller doesn't build queries, the repository does. You just ask it what you want and it magically delivers.

Can a pure DDD approach be used with NHibernate?

I've been reading up on DDD a little bit, and I am confused how this would fit in when using an ORM like NHibernate.
Right now I have a .NET MVC application with fairly "fat" controllers, and I'm trying to figure out how best to fix that. Moving this business logic into the model layer would be the best way to do this, but I am unsure how one would do that.
My application is set up so that NHibernate's session is managed by an HttpModule (gets session / transaction out of my way), which is used by repositories that return the entity objects (Think S#arp arch... turns out a really duplicated a lot of their functionality in this). These repositories are used by DataServices, which right now are just wrappers around the Repositories (one-to-one mapping between them, e.g. UserDataService takes a UserRepository, or actually a Repository). These DataServices right now only ensure that data annotations decorating the entity classes are checked when saving / updating.
In this way, my entities are really just data objects, but do not contain any real logic. While I could put some things in the entity classes (e.g. an "Approve" method), when that action needs to do something like sending an e-mail, or touching other non-related objects, or, for instance, checking to see if there are any users that have the same e-mail before approving, etc., then the entity would need access to other repositories, etc. Injecting these with an IoC wouldn't work with NHibernate, so you'd have to use a factory pattern I'm assuming to get these. I don't see how you would mock those in tests though.
So the next most logical way to do it, I would think, would be to essentially have a service per controller, and extract all of the work being done in the controller currently into methods in each service. I would think that this is breaking with the DDD idea though, as the logic is now no longer contained in the actual model objects.
The other way of looking at that I guess is that each of those services forms a single model with the data object that it works against (Separation of data storage fields and the logic that operates on it), but I just wanted to see what others are doing to solve the "fat controller" issue with DDD while using an ORM like NHibernate that works by returning populated data objects, and the repository model.
Updated
I guess my problem is how I'm looking at this: NHibernate seems to put business objects (entities) at the bottom of the stack, which repositories then act on. The repositories are used by services which may use multiple repositories and other services (email, file access) to do things. I.e: App > Services > Repositories > Business Objects
The pure DDD approach I'm reading about seems to reflect an Active Record bias, where the CRUD functions exist in the business objects (This I call User.Delete directly instead of Repository.Delete from a service), and the actual business object handles the logic of things that need to be done in this instance (Like emailing the user, and deleting files belonging to the user, etc.). I.e. App > (Services) > Business Objects > Repositories
With NHibernate, it seems I would be better off using the first approach given the way NHibernate functions, and I am looking for confirmation on my logic. Or if I'm just confused, some clarification on how this layered approach is supposed to work. My understanding is that if I have an "Approve" method that updates the User model, persists it, and lets say, emails a few people, that this method should go on the User entity object, but to allow for proper IoC so I can inject the messagingService, I need to do this in my service layer instead of on the User object.
From a "multiple UI" point of view this makes sense, as the logic to do things is taken out of my UI layer (MVC), and put into these services... but I'm essentially just factoring the logic out to another class instead of doing it directly in the controller, and if I am not ever going to have any other UI's involved, then I've just traded a "fat controller" for a "fat service", since the service is essentially going to encapsulate a method per controller action to do it's work.
DDD does not have an Active Record slant. Delete is not a method that should be on an Entity (like User) in DDD.
NHibernate does support a DDD approach very well, because of how completely divorced it remains from your entity classes.
when that action needs to do something
like sending an e-mail, or touching
other non-related objects
One piece of the puzzle it seems you are missing is Domain Events. A domain entity shouldn't send an email directly. It should raise an event in the Domain that some significant event has happened. Implement a class whose purpose is to send the email when the event occurs, and register it to listen for the Domain Event.
or, for instance, checking to see if
there are any users that have the same
e-mail before approving
This should probably be checked before submitting the call to "approve," rather than in the function that does the approving. Push the decision up a level in calling code.
So the next most logical way to do it,
I would think, would be to essentially
have a service per controller
This can work, if it's done with the understanding that the service is an entry point for the client. The service's purpose here is to take in parameters in a DTO from the front end/client and translate that into method calls against an entity in order to perform the desired funcitonality.
The only limitations NHibernate creates for classes is all methods/properties must be virtual and a class must have a default constructor (can be internal or protected). Otherwise, it does not [edit] interfere with object structure and can map to pretty complex models.
The short answer to you question is yes, in fact, I find NHibernate enhances DDD - you can focus on developing (and altering) your domain model with a code first approach, then easily retro-fit persistence later using NHibernate.
As you build out your domain model following DDD, I would expect that much of the business logic that's found you way into you MVC controllers should probably reside in your domain objects. In my first attempt at using ASP.NET MVC I quickly found myself in the same position as yourself - fat controllers and an anemic domain model.
To avoid this, I'm now following the approach of keeping a rich domain model that implements the business logic and using MVC's model as essentially simple data objects used by my views. This simplifies my controllers - they interact with my domain model and provide simple data objects (from the MVC model) to the views.
Updated
The pure DDD approach I'm reading about seems to reflect an Active Record bias...
To me the active record pattern means entities are aware of their persistance mechanism and an entity maps directly to a database table record. This is one way of using NHibernate e.g. see Castle Active Record, however, I find this pollutes domain enitities with knowledge of their persistence mechanism. Instead, typically, I'll have a repository per aggregate root in my domain model which implements an abstract repository. The abstract repository provides basic CRUD methods such as:
public IList<TEntity> GetAll()
public TEntity GetById(int id)
public void SaveOrUpdate(TEntity entity)
public void Delete(TEntity entity)
.. which my concrete repositories can supplement/extend.
See this post on The NHibernate FAQ which I've based a lot of my stuff on. Also remember, NHibernate (depending on how you set up your mappings) will allow you to de-persist a complete object graph, i.e. your aggregate root plus all the objects hanging off it and once you've finished working with it, can cascade saves through you entire object graph, this certainly isn't active record.
...since the service is essentially going to encapsulate a method per controller action to do it's work...
I still think you should consider what functionality that you currently have in your controllers should, more logically, be implemented within your domain objects. e.g. in your approval example, I think it would be sensible for an entity to expose an approve method which does whatever it needs to do to within the entity and if, as in your example, needs to send emails, delegate this to a service. Services should be reserved for cross-cutting concerns. Then, once you've finished working with your domain objects, pass them back to your repository to persist changes.
A couple of books I've found useful on these topics are:
Domain-Driven Design by Eric Evans
Applying Domain-Driven Design and Patterns by Jimmy Nilsson

MVC: Repositories and Services

I am confused as to the limitations of what gets defined in the Repositories and what to leave to the Services. Should the repository only create simple entities matching tables from the database or can it create complex custom object with combinations of those entities?
in other words: Should Services be making various Linq to SQL queries on the Repository? Or should all the queries be predefined in the Repository and the business logic simply decide which method to call?
You've actually raised a question here that's currently generating a lot of discussion in the developer community - see the follow-up comments to Should my repository expose IQueryable?
The repository can - and should - create complex combination objects containing multiple associated entities. In domain-driven design, these are called aggregates - collections of associated objects organized into some cohesive structure. Your code doesn't have to call GetCustomer(), GetOrdersForCustomer(), GetInvoicesForCustomer() separately - you just call myCustomerRepository.Load(customerId), and you get back a deep customer object with those properties already instantiated. I should also add that if you're returning individual objects based on specific database tables, then that's a perfectly valid approach, but it's not really a repository per sé - it's just a data-access layer.
On one hand, there is a compelling argument that Linq-to-SQL objects, with their 'smart' properties and their deferred execution (i.e. not loading Customer.Orders until you actually use it) are a completely valid implementation of the repository pattern, because you're not actually running database code, you're running LINQ statements (which are then translated into DB code by the underlying LINQ provider)
On the other hand, as Matt Briggs' post points out, L2S is fairly tightly coupled to your database structure (one class per table) and has limitations (no many-many mappings, for example) - and you may be better off using L2S for data access within your repository, but then map the L2S objects onto your own domain model objects and return those.
A repository should be the only piece of your application that knows anything about your data access technology. So it should not be returning objects generated by L2S at all, but map those properties to model objects of your own.
If you are using this sort of pattern, you may want to re think L2S. It generates up a data access layer for you, but doesn't really handle impedance mismatch, you have to do that manually. If you look at something like NHibernate, that mapping is done in a more robust fashion. L2S is more for a 2 tier application, where you want a quick and dirty DAL that you can extend on easily.
If you're using LINQ then my belief is that the repository should be a container for your LINQ syntax. This gives you a level of abstraction of the database access routines from your model object interfacing. As Dylan mentions above there are other views on the matter, some people like to return the IQueryable so they can continue to query the database at a later point after the repository. There is nothing wrong with either of these approaches, as long as you're clear in your standards for your application. There is more informaiton on the best practices I use for LINQ repositories here.

Resources