Dal (with Entity Framework) and Model layers into MVC - c#

First of all , I use EF into Dal layer (separeted project from MVC, same solution). The generated models from EF's EDMX file are the actual models from Model layer?? If so, how do I access these models to work in MVC's View layer? I think it's wrong accessing data layer directly from view to work with these models, and If I make a Model layer with "my models" and translate Dal's models into mine models... it'll be duplicated code.
Probably I'm getting something wrong, but most of egs. are with code first approach, and I can't figure out this.

You are right in your idea of not accessing access the Models in your DAL directly from your presentation layer.
To avoid duplicating code when translating your DAL objects into the Models used by your views, you could use something like AutoMapper, which is supposed to do the heavylifting for you in exactly that scenario.

I think it's wrong accessing data layer directly from view to work with these models...
That's right, the appropriate method is using View Model
When you have dozens of distinct values to pass to a view, the same flexibility that allows you to
quickly add a new entry, or rename an existing one, becomes your worst enemy .You are left on your
own to track item names and values; you get no help from Microsoft IntelliSense and compilers .
The only proven way to deal with complexity in software is through appropriate design. So defining an object model for each view helps you track what that view really needs. I suggest you define a
view-model class for each view you add to the application.
-- "Programming Microsoft ASP.NET MVC" by Dino Esposito
A ViewModel provides all information that your view requires to make itself. To transfer data from ViewModel and a business entity you can use AutoMapper.
Don't worry about duplication, those are two different concept and should be separated from each other; it makes your application easy to maintain.

I may be mistaking but to me, using generation from EDMX provides you with the DbContext which could be considered as the DAL and entities which could be considered as the Model.
So you might directly manipulate entity instances as your business object. Manipulation of the base through the DbContext should appear in the BLL layer. Additionally, you might implement DTOs where needed.
This, of course, assumes you want to use entity framework code generation. Other options like using POCOs might be more relevant considering your overall architecture.

I use a view model in my local project and the models in the other project. Then put references to the models im gonna use on the page in my view model. Then reference the view model on my page. Let me know if that sounds like something you want to do and I can edit in some code.

Related

Entities cannot be tracked by more than one context, interferes with N-tier design

I have a colleague who insists I develop ASP.Net MVC websites using an n tier data access layer and MVVM.
He has a background in Silverlight and WPF and I have attempted to create a solution but it is causing problems.
I created and DAL and logic layers (using generics):
Dal - containing a repository pattern that wraps up entity frame work.
Logic - pass through layer, no generic logic to apply currently.
I am still using the MVC pattern and am passing the Entity framework model to View unless the need additional properties or methods - in which case I create a view model and an interface to map between the two.
The n tier data access layer has locked the entity framework context at the bottom of the stack and the main problem I have that entities can't be tracked on more than one context. ({"An entity object cannot be referenced by multiple instances of IEntityChangeTracker."})
I recently came across a problem where context coming up with this error despite my attempts despite to use models, interfaces, deep copying.
The issue here is this was the approach I was going to take to try and put a model in the DAL layer and map the data between entity framework entity and model.
I understand the underlying issue: that even though you dispose of a context it doesn't release the entities that were attached to it. Is there anyway to get this n tire data access approach to work with MVC? or am right this will never work and I should stick to using the entity framework context in the controller method (or underlying class implemented using dependency injection).
There's a lot to unpack here.
If you are looking for an MVVM implementation, then you are going to want to look at something like knockout.js. Or some other framework that is going to do declarative databinding in the client side. there are a number of articles that you can read to understand this.
https://learn.microsoft.com/en-us/aspnet/core/client-side/knockout
but let's start with the assumption that you aren't going down that road and want to stick with MVC.
I would stop passing entities to your views. You are going to cause yourself endless grief. Create a view model for each corresponding view. you use of an interface seems like overkill. You can project linq queries for your entities/repos right into the the view models. you could also use something like Automapper to map from entity to view model. Appending some of your code to the questions might help. And my view models tend to be pretty flat. I don't see why you would need to perform deep copies of entity trees out to the view. Those can be gotten latter using partial views or some other method.
Now that you aren't sending entities out to the view, when you post information for updating, you are going to have to instatiate a new object for fetch the object you are looking to update from ef again. make your changes and save.
To me that simplest implementation is the best. I would pass you context to the controller method (preferably using an IoC) and querying the context directy in the controller action and projecting directly into the view model. If you've got a lot of shared code between controller actions, maybe move stuff into a service and then inject the service into the controller and inject the context into the service. but i'd start with just injecting the context into the controller.

Handling Mismatch Between Domain and Code First Entities

I am using Code First approach and there are some mismatch between my model for code first approach (DAL) and my domain model (BLL). I imagine my Data Model to have annotations, properties, configurations, etc related to database only and not the same for my Domain model entities and vice versa to obey separation of concerns.
How do I go about handling this situation in my application? This is more logical then technical I guess. Asked before in many places but no concrete lead yet. Hope some suggestion from SO will help.
In my experience because of the rich mapping possibilities of the Entity Framework you don't have to separate a Data access and Business logic layer at all, you just have to use the Fluent API of the Entity Framework. In one of my current project we have more than 150 classes with inheritance hierarchies and all but we can still use it without "duplicating" the objects.
Some good introductions about the fluent API can be found here:
http://msdn.microsoft.com/en-us/data/hh134698.aspx
http://msdn.microsoft.com/en-us/magazine/hh852588.aspx
About the separation: we simply use a Domain project and a Persistence.EntityFramework project where the latter contains all the mappings thus the Domain does not reference the EntityFramework.dll at all.
And if you have some specific mapping questions e.g. the ones you mentioned that are the reasons you created two layers one for DAL and the other for BL just ask them.
I would go with AutoMapper. It can help you to reduce the boilerplate code needed to convert from one object to another.
You can find it here:
https://github.com/AutoMapper/AutoMapper
Edit:
Put your domain models either in BLL or in a separate project, add reference to the BLL or this separate project in the DAL (also reference the new project in BLL), and use the AutoMapper in the DAL. So only domain models will leave the DAL.
You normally have:
A domain model (entities), which is what the O/RM (Entity Framework) uses;
A Data Transfer Objects (DTO) model, used for sending data to a view (in MVC) or by web services, etc.
I agree with Andras: the best way to go from one (domain) to the other (DTO) is by using Automapper. Of course, you can also do it by hand.
One thing that you need to realize is that there is no need for a 1-1 mapping between the domain and the DTO, the DTO can contain denormalized or calculated properties as well.

Layer ASP.NET MVC Project

I am trying to understand the concepts of a good designed project.
I am using ASP.NET MVC and i am trying to create a layered (pluggable) project.
The current project structure what i have now is this:
LayeredProject - the MVC Project containing Controllers
LayeredProject.EntityFramework - contains all the POCO classes used for database. (i am using Code First approach)
LayeredProject.Model - this should contain all the business objects used in the project.
Saying that the project is a eCommerce website, i would structure it like this:
In the LayeredProject.EntityFramework project i have classes which corresponds to the database tables. Category, Product, User. This project is used only for saving and loading data from database, and those objects should not be used for other purposes. This project has a reference to LayeredProject.Model project.
In LayeredProject.Model project i store all the objects i work with, which most of them are exactly copies of LayeredProject.EntityFramework POCO's objsects and some other Services Classes used.
In LayeredProject i keep all my ViewModels classes, Controllers, and different UI logic. This project has a reference to LayeredProject.Model project.
First of all, i am not sure that this is the right way of doing this.
And, it this is the right way of doing it, then i get a little confused because i will have a duplicate of my POCO classes in EntityFramework project and also on Model project.
Please help me understanding this
You can Design Your Project using layered structure as well using MVC. The Controller and view part should stay intact. You can divide the business logic part as many layers as you want. The model should come as a result of the number of layers you are expecting. For this keep your business logic in a separate project (not neccessary: it can be there in web project itself), refer the dlls from that project to the MVC web solution. Pass the models which are generated as a result of database querying to the web solution and with the help of controller render the view.(I have done my project using this style)
The MVC project should contain:
view models: models for the views, i.e. models that are very specific to render each view (these model are not the M in MVC). This models usually contain the data which must be shown or edited in the view, as well as aditional necessary information to render the view: for example, if the view must render Drop Down Lists, the view model should contain the corresponding SelectList or IEnumerable to populate the list. You can use mappers, like AutoMapper or ValueInjecter to move data from the business entities (entities coming from the Business Layer) to the view models, and viceversa. Or if appropriate, you can use directly the business entities as properties in the model view (the view model doesn't need to be flat: it can contain objects as properties)
views, strongly typed with the view models
controllers: this controllers use the Business Logic (that is the Model, the M in MVC) to control the application flow, to create and provide the model views for the views, and to react to the user actions
UI helper: I usually add this layer to fulfill the DRY principle. I.e. if I have to prepare a SelectList and it's going to be used in many views, I do it in this layer, and use it from all the necessary places. This can include calculations, orderings, or anything tighly related to the UI, so it doesn't fit in the Business Layer (Model). This uses the Business Layer, and provides data specific for the Views.
Those are the specific and critical parts of MVC, which includes the VC in MVC (views and controllers) The M in MVC (Model) is the business logic which can be done 'as usual'. I.e. you don't have to do anything special in your business layer to use it with MVC. You can use the technology of your choice (a traditional DAL + BLL, WCF, WS, or whatever you want).
This is something which works well for LOB applications. Of course, if you're making a toy application, you can forget this all and make something more monolythic. But I only recommedn this for very little applications with scarce maintenance needs.
These are examples of objects in several layers that allow to edit a "Pet":
Business Logic Layer:
PetService, a class which can be use to read, write, find, and modify pets (as explained above it doesn't matter how this is implemented)
Business Entity: it's the BLL entity for managing Pets. This could be a POCO object or a DDD entity:
Pet - int Id, int PetTypeId, string Name...
View Model: contains a Pet proerty, as well as a list of PetTypes, so that the view can render a drop down list for the PetTypeId:
PetViewModel - Pet ThePet, SelectList PetTypes
UI Helper: if the PetTypes is going to be used in more than one or two views, a PetUiHelper could provide this select list for all the views that require it:
PetUiHelper - GetPetTypesList()
Pet views: a strongly typed view for PetViewModel
Views\Pet\Edit.cshtml
PetController: uses the PetService to create the views, and their model views.
PetController - Edit(int id) --> returns an Edit view, woth its corresponding PetViewModel. There must be also an HttpPost Edit action which receives the user input in an specific model or the PetViewModel, or the Pet plus the Id or whatever. This depends on what you're editing.
Finally, if you know how to use DI, you can use Unity.Mvc or any of the other options to inject the Business Services in the controllers.
seems your using the Code First approach to build a data access, you can dig in this extensive article and gain more insight.
http://ofps.oreilly.com/titles/9781449320317/ch_AdvancedData.html
You probably have one too many layers in there, there should be no reason to separate the model with the business logic from the LayeredProject MVC layer itself unless you are planning to have a client app or some other separate project to access the model. In the MVC project you already have a model folder that can be used for that. However in the MVC project you should also add a "ViewModels" folder to keep models that are specifically used for the view concerns (e.g. DTO objects).
This project shows a nice simple way of keeping the things separate simply within folders in the MVC project: RacoonBlog Project. Although it uses RavenDB rather than EF the ideas are the same.
Most MVC apps I have worked were layered in this way
MVC Project: Had the controllers, views and models. The business logic resides in the model.
The Data Access layer (Persistence layer) : This project uses an ORM. (In your case entity frame work)
Classes that are mapped to the database tables reside in the Model and not the data access layer.

.NET N-Tier Architecture: What do I do about the Model objects?

I am creating a solution from scratch, using ASP.NET Web forms C#.
I am concerned about the model objects as I don't want to create duplicate sets of model objects in each layer. What is the best practice for using Model objects in 3 layer architecture in Web Forms?
The structure I have in mind is as follows:
UI
BLL
DAL
Model
The Model will contain all the model classes that can be used in each section of the layers. I thought this would be useful as each layer needs access to the model objects. For example:
UI calls a method in BLL passing in a model object filled with data.
BLL calls a method in DAL passing through the object which is saved
in the database etc.
Thanks
Models can be a cross-cutting concern with your layers, which is a quick way to do it. Or you can create interfaces for your models such that you could simply flesh out the interface in something like the BLL - this at least stops it being cross-cutting.
It further depends on if your models are simple data containers (anemic domain model), or contain behaviour, such as the ability to validate themselves or track changes themselves (rich domain model).
You can find that your DAL actually consists of two parts: the boilerplate-never-specific to an app code to talk to the database, and the app-specific populate-the-model code. We have this situation. We share interfaces of our models around, the app-specific DAL code can use this interface in order to push and pull data from the model, but the "true" DAL code works with raw stuff.
In a relatively small application, you can share your Domain Entities all the way up to your Presentation layer but be aware of the coupling this introduces.
If in your Databinding you except an Entity of type Customer with a property Address with a StreetLine1 and StreetLine2 property then all your layers are tightly coupled together and a change in one layer will probably cause changes in other layers.
So your decision should be based on the scale of your project and the amount of coupling you can have.
If you go for a low coupled design then your BLL will use your DAL to retrieve entities and use those entities to execute behavior. The BLL will then use Data Transfer Objects to pass to your Presentation layer so there is no coupling between your presentation layer and your Domain Model.
look at my answer here: https://stackoverflow.com/a/7474357/559144  this is the usual way I do things and works well, not only for MVC and Entity Framework... in fact in MVC the model could be an entity type which only has some of the fields contained by the real business entities defined in lower layers, it depends if you really absolutely need all fields in the UI level as well or only some to do some data rendering and input... 
As a related topic, please see this related answer which I posted recently on avoiding duplication of code and correct architecture in a cross-platform client/server system.
I have +1'd the other posters in this thread as this is not intended to be a full answer, just useful information related to the question.
Best regards,

Repository, Pipeline, business logic and domain model - how do I fit these together?

I'm designing N-tier application and I came across a difficulty which you might have a solution to. Presentation layer is MVC.
My ORM is carried out using LinqToSQL - it's a seperate project which serves repositories.
Each reporsitory has an interface and at least 1 concrete implementation.
Repositories have the following methods: FindAll(), Save(T entity), Delete(int id)
FindAll() returns IQueryable of some type, which means that it returns queries to which I can apply filters.
ORM mapping has been carried out using Database First methodology, where tables were created first and then classes were generated by SQL Metal.
I have added a Pipeline layer which works with repositories. It applies further filters to queries. E.g. OrderRepository.FindAll().Where(o => o.CustomerId == 10)
Pipeline also returns IQueryable of some type, which means that I can pass it further up the layer and do more stuff with it.
At this point I would like to move to the BusinessLogic layer, but I don't want to work with entity models any longer, I want to convert entity model to a domain model. This means that I can add validation to a model and use that model in the presentation layer. Model can't be defined in MVC project as it would be dependant on the presentation layer, so that's a no.
I'm fairly certain that business logic (behaviour) and model must be stored seperate from pipeline, data and presentation layer. The question is where?
For example, a pipeline has three methods:
1. FindByCustomerId
2. FindByOrderId
3. FindBySomethingElse
All these methods return IQueryable of Order. I need to convert this to a domain model, but I don't want to do it per each method as it won't be mainteinable.
I feel that this model is fairly robust and scalable. I just don't see what is the best place for mapping from entities to domain model and vise versa.
Thank you
First of all, if you are applying Domain Driven Design principles here, you must not have BusinessLogic layer in your application. All business logic should live inside your domain model.
But it is quite hard to achieve using LinqToSQL because it does not support inheritance mapping and you would have to deal with partial classes to put business logic into your domain. So I would strongly recommend to consider moving from LinqToSQL to NHibernate or Entity Framework Code First .In this case you also won't have to convert your persistence model into your domain model and vice versa.
If you still want to do conversion, you could take a look at Automapper
From a domain driven point of view you would need a factory to convert your 'database entity' into a domain model entity.
When you're thinking of turning the 'database entities' to domain model entities at the end of your pipeline you should realize that after the conversion to domain model entities (a projection) you won't be able to use the IQueryable functionality as the projection will trigger execution of your expression tree. For example if you call FindAll for you customer database entity and then convert the IQueryable to (or project it onto) a customer domain entity it will execute (requesting the contents of your entire table).
This is how I do my N-Tier projects. This architecture has great separation of concerns. It sounds like you are already headed in this direction.
In the Mvc project is all your usual objects (Controllers, ViewModels, Views, helpers, etc). Fairly straight forward. All views are strongly typed. Plus my modified T4 templates that generate Controllers, Views, and ViewModels.
In the Business Model project I have all my business objects and rules, Included are the interfaces that define functionality of the data repositories. Instead of having one repository for every business object / table I prefer to group mine by functionality. All objects related to a blog are in one repository while all objects related to a photo gallery are in a separate repository, and logging may be in a third.
You could place your pipeline layer here.
In the Data project I implement those data repository interfaces. You can use Linq2SQL without having to use partial classes. Extending those Linq2SQL partial classes means you have tied your ORM to your domain model. Something you really don't want to do. You want to leave those generated data classes in the data domain. Here is an example Linq2SQL select that returns a BusinessModel object.
from t in Table
where t.Field == keyField
select new BusinessModel.DataObject
{
Id = t.Id,
Field1 = t.Field1,
Field2 = t.Field2
}
If I were you I would look at EntityFramework 4.1 using the CodeFirst approach or use NHibernate. Either of these will map your data model to the domain model. Then to map the domain models to the view models you could use AutoMapper or write custom code or write a T4 template that would generate the mapping code for you.
You could take the code generated by the dbml file as a starting point for your business objects.
Further to xelibrion's comments you could have a look at LightSpeed for your ORM needs. You are currently using LinqToSQL so you should find Lightspeed very straight-forward since it uses the same idea.
http://www.mindscapehq.com/products/lightspeed
If you can get your data to map Models that more match the form your higher levels want then hopefully you can simplify things. The less complexity in the system the less scope for bugs.
All these methods return IQueryable of
Order. I need to convert this to a
domain model, but I don't want to do
it per each method as it won't be
mainteinable.
This is not a true assessment and is probably blocking you from seeing the proper solution.

Categories