Which layer should i place .edmx and generated POCO classes? - asp.net-mvc

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.

Related

Entity Framework: Naming conventions/suggestions for EDMX file and entity class?

I´ve not had much contact with Entity Framework yet and therefore I´d like to hear some guys with experience.
I´ve got an MVC project and my DataAccess lies in a different project where I want to place my EDMX file.
So how would I like to name this file? Per default it is "Model1.edmx" but in the context of MVC I don´t feel comfortable with this name. Is it really a Model?
I tend to call it "DbModel" or something to indicate that it is database related stuff.
And how do you guys call the entity class? I think I like the EF typical name "DbContext".
So within my controllers I´d have something like
public class WorldController : Controller
{
DbContext db = new DbContext();
public ActionResult Own()
{
var allContinents = db.Continents;
[...]
}
}
Sorry for being fussy but I really do care about naming.
It is good to care about naming!
How to do it depends on the composition your application. Let's say you have a web application for registering UFO sightings, to name something common. If there is a separate part of your db (maybe a separate schema) containing users, roles and permissions, you could create a context named AuthorizationContext, and for the business part a context named UfoDbContext.
I mean, if there are clear aggregates with no or little overlap you could create separate contexts for them with clear names. If one context fits the bill, I would still give it some meaningful name (not DbContext) that relates to your application domain.
There are people (I'm not one of them) that like to work with one context per application "column" (db to UI) or "user story". Meaningful names are even more important then.
My suggestion would be to use something that indicates the contents in the naming. You could take part of your project name, for instance, and bring it down into the name of the EDMX. Include something that makes it less generic.
I also tend to include an "Ef" in my naming, which I started when working on a project that already had an existing ORM.
To take Microsoft's prototypical example: if your project fell under the umbrella name of Norwind, here's how I would name some of the files in my model project:
EDMX File:
NorwindEfModel.edmx
Generator/TT File:
NorwindEfDbContext.tt
Entities class:
NorwindEntities
I can't say this is exactly how Microsoft would have it if you downloaded a sample project from them (though I believe it would be similar), but I think it's a reasonable naming structure and it fits my needs. The bottom line is this largely comes down to opinion and your need for specific distinction.

EF 4.0 and stored procedures: return business objects or complex types?

I'm new to EF4 and I'd like to know what the best approach when using EF with stored procedures as part of the DAL. So far I have these two options:
Option 1
Using EF4, I can create a complex type that the EF will map my results from stored procedures. I can then return this complex type from the DAL layer and then convert it again into custom BLL object in the main application layer. This strategy is appealing to me since I would rely on EF4 designer to build the plumbing without me building parameters by hand. It also makes DAL stand alone without referencing the assembly that contains the business objects. The major issue that I see with this approach is the fact I have to sort of hydrate DAL complex type to BLL business object again. Not sure how it would affect the performance.
Option 2
Have DAL reference assembly that contains BLL object and then return BLL objects from DAL layer. I'm not really sure if this is the right approach for me. I would have to manually create stored procedure parameters and then iterate of DataReader to build business objects to return. It's doable, but I would rather let EF4 designer build me stored procedure plumbing. Also, it would seem to couple DAL with BLL assembly, which I'm not sure is appropriate.
Would appreciate some comments on this and suggestions.
Thanks!
There is a third option - make your business objects entities. EF is tool to persist and retrieve business objects from the database but you make it just data access layer with need to manually convert its results to business objects. That is whole source of your problems.

ASP.NET MVC - is it okay to have sideline presentation logic?

In most documentation you read about ASP.NET MVC, the entire 'Separation of Concerns' is very heavily pushed. Dependency Injection/Inversion of Control, Unit Testing, keeping 'logic' out of the Views, etc.
But how far is this intended to be pushed? Is it bad practice if a specific task requires extra logic beyond the 'three layer' approach of View/Model/Persistence?
For example, I have a solution set up with four individual projects.
Project.Web (ASP.NET MVC) [ References Data.dll, Models.dll ]
Project.Data (Fluent nHibernate Mapping) [ References Models.dll ]
Project.Models (POCO, Helpers, Factories, etc)
Project.Tests (Unit Testing)
Up until now, this has served me pretty well. But I require some very abstract logic for some of my MVC Views, such that I need to take part of the Models and arrange a View Model that is persisted in the database.
This cannot happen in my Data section, as that would dispose the re-usability of it, and there is business logic included in the process. It cannot entirely happen in my Models section, because that would require it to have knowledge of the Data section, which it does not. And I do not want to put it in the Web section because I don't want data access code there.
Question
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to? Moreover project concerns aside, is this a bad approach in general or is this something a lot of you find yourselves having to do at times? Part of me feels that if I am having to resort to this, then I've just built my software wrong - but at the same time I am very confident I have done a fairly good job, it is just too abstract to make a raw HTML interpretation of without middle-man arrangement.
It's been my experience that single responsibility is a great way to write code you expect to change early and often. Like Jan, I too have a solid line between who does what, when. The more you enforce this, the easier it is to replace an slice of your system. I recently removed linq2sql with EF4.1 and because of SRP, once I got the tests passing around my new EF4 layer, everything else just worked.
That said, I typically let unit testing dictate where these things live -- it's my driver for SRP as well as asking the basic question "must =class/service= know about =something else= to do it's job?" If the answer is no, it goes somewhere else -- if yes, it's a dependency. Now, if it becomes painful, that's its way of telling me "this is stupid" (see this question for the stupid) and I've attempted to force something instead of allowing it to fit the way it must.
Onto your core queston : you've clearly identified a gap in your code -- it MUST know about two things (data and model) and I agree, it should be its own thing and pulled out. I would call this a "DomainService" or maybe just DTO, but presentation feels like it would be doing more than just prepping data. (I'd argue the view handles the presentation ... maybe you simlpy mean presenter?). I would also argue against your perception that you did "something wrong" - no, you're learning to write code differently and allowing it to evolving, EXACTLY as it should. :-)
I use the following structure, which more or less solves all problems we've had regarding MVC structures.
Models: contains all ViewModels. Just clean, only getters and setters.
Business logic implementation: Set of projects that contains database logic, DAL entities etc. But only has one interface (in our case this is a WCF API).
ServiceLayer: the bridge between Business Logic and ViewModels. Doesn't know anything about web.
Mapping layer: translation between business entities and ViewModels.
Web project: holds very thin Controllers and Views, and everything web related.
A web page flow will follow this flow:
URL maps to a certain Action
Actions are really clean, they only reference a method in the ServiceLayer
The ServiceLayer executes one or more actions in the Business Logic Implementation (get data, store data, etc.)
The ServiceLayer passes the business entities to the Mapping Layer.
The Mapping Layer translates business entities into ViewModels
In code this would look like:
// action
public ActionResult ListOfObjects () {
var model = new ServiceLayer.ObjectsClient().GetListOfObjects();
return View(model);
}
// Service Layer
public ListOfObjectsModel GetListOfObjects () {
var businessEntities = BusinessDao.GetThingysFromDb();
var model = Mapper.TranslateToViewModel(businessEntities);
return model;
}
// Mapping Layer
public ListOfObjectsModel TranslateToViewModel(List<BusinessEntity> entities) {
// do mapping
}
When handling POSTs you will follow the same flow, but the mapping layer should translate your ViewModel into Data Entities that are given to the Business Logic.
"take part of the Models and arrange a View Model that is persisted in the database"
Then its not a viewmodel.
Does that simplify things?
What is a 'ViewModel':
More than often 'ViewModel' is confused with persistence. If you look at the word more closely it is a combination of 'View' + 'Model' - which essentially means it is a single unit of data that is required to fulfill all the needs of your view. A ViewModel can infer multiple entities or sources to build what is required by the View.
Now Coming to your question:
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to?
Re: If I had to do it, I would have created a seperate namespace (folder) in my MVC project named 'ViewModels' and placed all my Viewmodels in there. In my opinion if you want your ViewModels to be in a separate namespace, it would not actually violate MVC. You are just incresing the separation or making it more unit test friendly.
Just my 2 cents!!!

MVC + Repository Pattern - Still depends on Data Model?

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

Is my ASP.NET MVC application structured properly?

I've been going through the tutorials (specifically ones using Linq-To-Entities) and I understand the basic concepts, however some things are giving me issues.
The tutorials usually involve only simple models and forms that only utilize basic create, update and delete statements. Mine are a little more complicated, and I'm not sure I'm going about this the right way because when it comes time to handle the relationships of a half dozen database objects, the tutorials stop helping.
For the post method, the usual way of performing CRUD operations
entities.AddToTableSet(myClass);
entities.SaveChanges();
Won't do what I want, because a fully implemented class isn't getting posted to the controller method. I may post individual fields, form collections, or multiple DTO objects and then call a method on a service or repository to take the information I receive from a form post, along with information that it needs to query for or create itself, and then from all of those things, create my database object that I can save.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA,
[Bind(Exclude = "Id")]ClassB classB)
{
// Validation occurs here
if(!ModelState.IsValid)
return View();
try
{
_someRepositoryOrService.Add(id, classA, classB);
return RedirectToAction("Index", new { id = id });
}
catch(Exception ex)
{
// Logging and exception handling occurs here
}
}
public void Add(int id, ClassA classA, ClassB classB)
{
EntityA eA = new EntityA
{
// Set a bunch of properties using the two classes and
// whatever queries are needed
};
EntityB eB = new EntityB
{
// Set a bunch of properties using the two classes and
// whatever queries are needed
};
_entity.AddToEntityASet(eA);
_entity.AddToEntityBSet(eB);
_entity.SaveChanges();
}
Am I handling this correctly or am I bastardizing the framework? I never actually use an entity object directly, whenever I query for one I put the information I need in a DTO and base my Views off of that. Same goes with the creation. Is this allowed, or is my avoidance of using entities directly going against the purpose of using the framework?
Edit: I'm also worried about this approach because it requires empty constructors to properly do the LINQ queries because of this error message:
Only parameterless constructors and
initializers are supported in LINQ to
Entities.
This isn't a big deal since I rarely need logic int the constructors, but is this an issue to have no constructors and only public properties?
_someRepositoryOrService.Add(id, classA, classB);
I would say you couple your repositories with presentation layer. This shouldn't be. Your repositories should only work with entities. Next, notice how your Add method
public void Add(int id, ClassA classA, ClassB classB)
breaks Separation of Concerns (SoC). It performs two tasks:
map view data into entities
save to repository
Obviously the first step should be done in presentation layer. Consider using model binders for this. It can also help you to solve the constructors problem, since your model binders can be made aware of the construction requirements.
Check also this excellent post by Jimmy Bogard (co-author of ASP.NET MVC In Action) about ViewModels. This might help you to automate mapping. It also suggest a reversed technique - make your controllers work with entities, not ViewModels! Custom action filters and model binders are really the key to eliminate routine that that don't really belong to controllers but rather an infrastructure detail between view and controller. For example, here's how I automate entities retrival. Here's how I see what controllers should do.
The goal here is to make controllers contentrate on managing business logic, putting aside all the technical details that do not belong to your business. It's techical constraints that you talk about in this question, and you let them leak into your code. But you can use MVC tools to move the to them infrastructure level.
UPDATE: No, repositories shouldn't handle form data, that's what I mean by "coupling with presentation". Yes, repositories are in the controller, but they don't work with form data. You can (not that you should) make form work with "repositories data" - i.e. entities - and that's what most examples do, e.g. NerdDinner - but not the other way. This is because of the general rule of thumb - higher layers can be coupled with lower ones (presentation coupled with repositories and entities), but never low level should be coupled to higher ones (entities depend on repositories, repositories depend on form model, etc).
The first step should be done in the repository, that's right - except that mapping from ClassX to EntityX does not belong to that step. It's mapping concern - an infrastructure. See for example this question about mapping, but generally if you have two layers (UI and repositories) they shouldn't care about mapping - a mapper service/helper should. Beside Jimmy's blog, you can also read ASP.NET MVC In Action or simply look at their CodeCampServer for how they do mapping with IEntityMapper interfaces passed to controller constructors (note that this is more manual and less-work approach that Jimmy Bogard's AutoMapper).
One more thing. Read about Domain Driven Design, look for articles, learn from them, but you don't have to follow everything. These are guidelines, not strict solutions. See if your project can handle that, see if you can handle that, and so on. Try to apply this techniques since they're generally the excellent and approved ways of doing development, but don't take them blindly - it's better to learn along the way than to apply something you don't understand.
I would say using DTOs and wrapping the Entity Framework with your own data access methods and business layer is a great way to go. You may end up writing a lot of code, but it's a better architecture than pretending the Entity Framework generated code is your business layer.
These issues aren't really necessarily tied to ASP.NET MVC in any way. ASP.NET MVC gives basically no guidance on how to do your model / data access and most of the samples and tutorials for ASP.NET MVC are not production worthy model implementations, but really just minimal samples.
It seems like you are on the right track, keep going.
In the end, you are using Entity Framework mostly as a code generator that isn't generating very useful code and so you may want to look into other code generators or tools or frameworks that more closely match your requirements.

Resources