MVC + Repository Pattern - Still depends on Data Model? - asp.net-mvc

I've started a project for school in which I am using ASP.NET MVC 2 + LINQ2SQL, and a business layer so my UI doesnt interact with the DB directly. My question is this:
In my MVC project, when bringing up views and passing around data, I still have to include my Data project for access to the classes in my Linq2Sql project. Is this correct?
Example:
Controller:
ClassesRepository cr = new ClassesRepository(); // this is from my Business project
Class classToEdit = cr.GetByClassId(id); // "Class" is from my data project
I still have to reference the Class class in my linq2sql data project - shouldn't my UI be completely independent of my data layer? Or maybe I'm going about this all wrong.

I prefer to have my Repository do the mapping internally to my own classes. So what I return from my repository is not the LinqToSql classes but my own. I then map the returned classes data into a model for each views.
So it looks like:
LinqToSQL class -> MyClass (output from Repository at this point) -> (controller maps to model for a specific view) MyModel.
Make sure to always make a model for each view. You can just use what your repository returns but that is a short cut and mapping it to their own view models will pay off in the future.

Take a look at the Golf Tracker Series at MVC Central, it does what you want and what Kelsey is describing.
http://www.mvccentral.net

Related

Implementing DAL and BOL

I'm Using MVC 3 and I'm having trouble using Entity Framework so I'm trying to understand what would be the best approach to implement my own DAL.
I manage several main entities in my system: User, Department, Calendar etc...
I'm trying to understand the best practice using this kind of tiered architecture.
Should the DAL implement methods that only return DataTables or DataSets or should it be familiar with the model\ business object (User, Department Calendar etc..)?
Should it hold the classes representing the different models\ business object ?
Where should I place the different repository classes are they part of the DAL as well?
1) Should the DAL implement methods that only return DataTables or DataSets
Absolutely not. DataTables and DataSets are artifacts of the past. DAL methods should take/return your DAL entities. For example if you are using Entity Framework those would be the autogenerated classes that EF created for you. Or if you are using EF Code First those would be the classes you wrote to map to your SQL tables
2) Should it hold the classes representing the different models\ business object ?
As explained in 1) the DAL layer should contain the entities that are mapped to your SQL tables as well as the implementation of the repository interface. The repository interface defines the operations with those entities. Inside the DAL layer you will implement this interface for Entity Framework (if this is what you intend to use). Inside the methods you will use the DataContext to perform the different operations with your entities.
3) Where should I place the different repository classes are they part of the DAL as well?
You should place them in the same assembly as your data access classes.
The ASP.NET MVC application will then consume the DAL layer. Your Controllers will simply take the repository interface as constructor parameter and inside the actions you will call various methods on it. You will then configure the Dependency Injection framework of your choice to inject the specific implementation of this repository interface into the controller. This implementation will be the one specific to Entity Framework.
But no matter what you do, don't forget to define view models inside the ASp.NET MVC application itself. Those could be placed inside the Models folder. The view models are the classes that you will be passing to your views. A typical controller action will use the repository to fetch one or more domain entities, map those entities to a single view model that you have defined for the particular view and finally pass the view model to the view. Of course this works the other way around: a controller action takes a view model as action parameter from a view, maps this view model to one or more domain entities and calls one or more methods from the repository passing those domain entities to them.

Which layer should i place .edmx and generated POCO classes?

This is regarding a layered design with EF DB First model.
So far i have not used Entity Framework before, used only Entities and placed on a different project with Domain/ DTO sub folders. Also referred the same in DataAccessLayer, Business Layer and MVC application and written a code with usual ADO.Net queries and prepared POCOs of my entities. No issues.
Now we are developing an application using Entity Framework DB First model. We choosen this DB First model, as the DB Design is not in our control. It is done by DBA.
I thought of reusing the old simple design here. But not sure where/which layer I should exactly fit the edmx file and the generated POCO classes. I didn't find any samples with layered architecture style uses DBFirst approach.
I referred this. http://aspnetdesignpatterns.codeplex.com But they use NHybernate
Here is the highlevel overview of old design.
Any suggestions on design/samples, please you are welcome.
Edit:
From the below answer, I think the entity framework produces the POCOs we could rename existing Entities/Domain layer to Domain Layer and putting the generated POCO classes there. Also we can simply keep .edmx in DataAccessLayer with the list of IRepository classes that wraps EF for TDD. Does this makes sence? or any valuable points?
Update:
Currently i removed DataAccessLayer and keep only Entities layer which
has a model.edmx file and classes generated by EF and also all
Repository classes implementing IRepository. I refer this into
Business Layer, MVC as well. Am i doing right? I feel like i am doing
a bad design :( Please suggest/help
Because you're unfortunately severely handicapped by the decision to create the database first, you will need to use an Anti-Corruption layer per Eric Evans' Domain-Driven Design.
This is a good solution for what to do when you're given a shitty interface that you absolutely must code against - make an interface wrapped around the DB that behaves the way you want it to. Do not expose any EF classes directly to anything except the anti-corruption layer itself.
Here's a reading example:
public class SomeReadService : ISomeReadService {
public SomeViewModel Load(Guid id) {
using (var dbContext = new DbContext()) {
// Query the DB model, then *map* the EF classes to SomeVieWModel.
// This way you are not exposing the shitty DB model to the outside world.
}
}
}
Here's a writing example:
public class SomeRepository : ISomeRepository {
public SomeDomainObject Load(Guid id) {
using (var dbContext = new DbContext()) {
// Map the EF classes to your domain object. Same idea as before.
}
}
}
I would still try to demonstrate to the client that having a separate team design the DB will be a disaster (and my experience strongly indicates that it will). See if there is some way you can provide the feedback that will demonstrate to the client that it would be better if you designed the DB.
Please see the SO link for similar kind of question below:
With a database-first approach, how do I separate my Core and Infrastructure layers?
Hope this helps !!
In my opinion, Entity Framework used correctly negates the need for a seperate DAL. I think of EF as my DAL. It allows you to concentrate on the business part more. EF does all the data access code for you. You can simply use your EF context in your business layer. To me, this is one of the best benefits of EF; that it is your DAL.
Depending on how you separate your layers (different assemblies or different folders within an assembly) depends where you put your POCO classes. If different assemblies (which is overkill for most projects) then a 'Common' assembly referenced by all others is the place to put POCO classes. If different folders, then a folder named 'Models' or 'DomainModels' is the place.
Specifically for an MVC application, I would put my POCO classes in the 'Models' folder (I also have a 'ViewModels' folder), and my .Edmx in a BLL folder which I sometimes call 'Logic'.
If you need a loosely coupled architecture for testing, then a folder named Repositories with the EF context wrapped in your own repository pattern is the way to go.
Edit:
The Short Answer is Data Access Layer (DAL)
You need to Enterprise architecture and it changes according your needs, but in your case Model Driving Design Pattern is the solid solution.
You can use MVC and you can drive your model from Poco or other entities like NHibernet etc.
No any importance about code-first or db-first, it is interesting just with the architecture creation phase.

How should I structure my code when the MVC's model do not match the database model?

I'm new to ASP.Net MVC and I'm having a question I can't seem to find the answer to on the Googles.
I have a page that needs a model that is significantly different from the way the data is stored in the database. It's trivial for me to write a function that would translate from the database model to the required MVC model (MyModel ConvertToMvcModel(DataFromDatabase d).
My question, where should I put this code? Should it be in the controler. Should it be in the Data access layer (Using the repository pattern).
Another related question is where should I put the repository class? Up until now I've put repository classes allong side the model class in the same .cs file since every model had a corresponding repository. This time the model will be different from what I get from the repository so it does not make much sense to put it in the same file. Maybe I should separate all my DAL (repositories) from the model code.
Any suggestions?
My question, where should I put this code?
The mapping between your domain models and view models should ideally be placed inside a separate and dedicated mapping layer. For example if you use AutoMapper, which I would recommend, you could place your mapping definitions inside separate files called profiles and inside the controller action simply call the Mapper.Map<TSource, TDest> method.
Another related question is where should I put the repository class?
Up until now I've put repository classes allong side the model class
in the same .cs file since every model had a corresponding repository.
The DAL represents the data access layer and is where the repositories should go. You could define a common contract (interface) that the repositories must obey (implement) and then have several implementations against the different data sources that you are working with.
You shouldn't return entities anyway, use ViewModels for that purpose.
Regarding the mapping: what you're looking for already exists, it's called AutoMapper. You can let the service layer return entities to your controller, and the controller will map them to ViewModel objects.
Keep in mind to initialize the mappings only one time, so launch them from your application start.

DTO Pattern + Lazy Loading + Entity Framework + ASP.Net MVC + Auto Mapper

Firstly, Sorry For lengthy question but I have to give some underlying information.
We are creating an Application which uses ASP.net MVC, JQuery Templates, Entity Framework, WCF and we used POCO as our domain layer. In our application, there is a WCF Services Layer to exchange data with ASP.net MVC application and it uses Data Transfer Objects (DTOs) from WCF to MVC.
Furthermore, the application uses Lazy Loading in Entity Framework by using AutoMapper when converting Domain-TO-DTOs in our WCF Service Layer.
Our Backend Architecture as follows (WCF Services -> Managers -> Repository -> Entity Framework(POCO))
In our application, we don't use View Models as we don't want another mapping layer for MVC application and we use only DTOs as View Models.
Generally, we have Normal and Lite DTOs for domain such as Customer, CustomerLite, etc (Lite object is having few properties than Normal).
Now we are having some difficulties with DTOs because our DTO structure is becoming more complex and when we think maintainability (with general Hierarchical structure of DTOs) we lose Performance.
For example,
We have Customer View page and our DTO hierarchy as follows
public class CustomerViewDetailsDTO
{
public CustomerLiteDto Customer{get;set;}
public OrderLiteDto Order{get;set;}
public AddressLiteDto Address{get;set;}
}
In this case we don't want some fields of OrderLiteDto for this view. But some other view needs that fields, so in order to facilitates that it we use that structure.
When it comes to Auto Mapping, we map CustomerViewDetailsDTO and we will get additional data (which is not required for particular view) from Lazy Loading (Entity Framework).
My Questions:
Is there any mechanism that we can use for improving performance while considering the maintainability?
Is it possible to use Automapper with more map view based mapping functions for same DTO ?
First of don't use Lazy Loading as probably it will result in Select N+1 problems or similar.
Select N + 1 is a data access anti-pattern where the database is
accessed in a suboptimal way.
In other words, using lazy loading without eager loading collections causes Entity Framework to go to the database and bring the results back one row at a time.
Use jsRender for templates as it's much faster than JQuery Templates:
Render Bemchmark
and here's an nice info for how to use it: Reducing JavaScript Code Using jsRender Templates in HTML5 Applications
Generally, we have Normal and Lite DTOs for domain such as Customer,
CustomerLite, etc (Lite object is having few properties than Normal).
Your normal DTO is probably a ViewModel as ViewModels may or may not map one to one to DTOs, and ViewModels often contain logic pushed back from the view, or help out with pushing data back to the Model on a user's response.
DTOs don't have any behavior and their purpose is to reduce the number of calls between tiers of the application.
Is there any mechanism that we can use for improving performance while considering the maintainability?
Use one ViewModel for one view and you won't have to worry about maintainability. Personally i usually create an abtract class that is a base, and for edit,create or list i inherit that class and add properties that are specific for a view. So for an example Create view doesn't need PropertyId (as someone can hijack your post and post it) so only Edit and List ViewModels have PropertyId property exposed.
Is it possible to use Automapper with more map view based mapping functions for same DTO ?
You can use AutoMapper to define every map, but the question is, how complicated the map will be. Using one ViewModel per view and your maps will be simple to write and maintain. I must point out that it is not recommended to use Automapper in the data access code as:
One downside of AutoMapper is that projection from domain objects
still forces the entire domain object to be queried and loaded.
Source: Autoprojecting LINQ queries
You can use a set of extension that are limited as of now to speed up your mapping in data access code: Stop using AutoMapper in your Data Access Code
Regards

Clean solution (project) structure with EF, Repositories, Entities

I like to keep the structure of the project as clean as possible.
Sample:
--BlogApp.sln
--BlogApp.Data
BlogModel.edmx (the EF mappings)
Post.cs (I end up having partial classes in here with attributes)
--BlogApp.Domain
--Entities
Post.cs (I would like to have my POCOs here with all its additional logic)
--Repositories
PostsRepository.cs
--BlogApp.Ui
(standard MVC structure)
I end up with mess when using EF as my ORM. Could anybody suggest some "clean" way to structure the project? Or maybe you could suggest some standard project structure that is most commonly used.
My preferred structure is:
Solution
-- Common
- Shared features used accross all layers
- You can also place interfaces for repositories and uow here
-- Entities - shared among DataAccess, Business (and UI in small projects)
- T4 template + partial classes + custom enums
- partial classes can contain methods with domain logic => domain objects
-- DataAccess - all EF dependent code here
- EDMX or code first mapping
- Repositories
- UnitOfWork
-- Business - not every project needs this assembly
- Business services
- Logic like workflows
- DTOs exposed to UI
-- UI
- Controllers
- Views
- ViewModels
Check out this write up on T4 Templates and the Entity Framework. You can write in custom attributes for entity properties generated via EF. I've done this several times, and after figuring out how to do it, it now saves a lot of time. I've tried using partial classes before as you mention, but my EF-generated class ends up overwriting the other with the custom attributes. Perhaps I was doing something wrong, but in any case, I now prefer the T4 template solution because it seems cleaner to me - minimizing on number of classes within a project.
Also, when you update your EF model from DB and the class is regenerated, your custom attributes are still in place. ftw!
ADDED:
By the way, we typically define our model objects within the Data layer to have them mapped/populated by EF's entities. Or (even simpler) use the EF-generated entities all the way through to the UI layer without custom defined POCOs.

Resources