0

I've been working with PHP ORMs, and an interesting point, due to be a dynamic language is: in data-access layer I make a request to DB and it returns a "generic" object (nice name for array!) and I use this as my actual model in entire application, straight on Controller and View! That amazes a strongly typed scenario!

Now in C#, using Entity Framework as my ORM, it have its own auto-generated models (Entities), and I had made a question about this here:

Dal (with Entity Framework) and Model layers into MVC

where the conclusion was: Is wrong to use these EF's entities as my actual Model-Layer in the application, so I need to get these Data-Layer models and transpose to the truly application model in Model-Layer... to work with received data from DB in my Controllers, Views..

Also, we have more awesome questions that helped me a little bit:

  1. Entity Framework in Layered Architectures
  2. In MVC, does an ORM represent the model?
  3. Entity framework and Business Layer / logic

But I'm rethinking about using EF in data-layer, why? The lovely thing in Entity Framework is the DbContext and basically all ORM works around it, and if I transpose these EF's entities to my model-layer models I'll be wasting all that goodies that make things easier and faster, besides of the hard work to transpose classes that really annoys me and make things harder ! (please don't say AutoMapper, I can't use this in my job, and I'm not searching for a third party solution).

Why using Entity Framework in Model-layer or in a single layer is faster:

I would have all the auto-generated models in the model layer, and I could use them in my entire application, also I'll take full advantage of all Entity Framework with DbContext, quick and easy.

However, that scares me because I would access data straight in a non-data layer and Controller and View can access all data-related stuff, and we all know about the problems about this approach.

So my question is:

I have assumed that ORM is to make data-access development easier and faster, simple as I can do with PHP an it works pretty well. Also, I assume that's perfect for agile development, because working with Stored Procedures for small and quick works is a pain (although I like SP). So here is Entity Framework and DbContext to make things easier and faster, right? But, agile development is not about to slap together at all, so that's why in all questions we're talking about placing EF in data-layer instead Model-Layer.

But this make development with EF slower and painful and we waste its advantages, and seriously, working with Stored Proceures in this case is faster. We don't have a really rapid development using EF in layered architectures?

Community
  • 1
  • 1
Wagner Leonardi
  • 4,226
  • 2
  • 35
  • 41
  • Tools like automapper make the translation from Entities to ViewModels relatively quick. I don't accept the premise of your question. – Maess Nov 21 '13 at 16:14
  • Ok if it works for you, but you don't know my scenario that I can't use it, and I have the right to make a question for another solution, okay? You could do -1 to my question, but you are being selfish – Wagner Leonardi Nov 21 '13 at 16:17
  • 1
    @Maess AutoMapper is definitely not the silver bullet that'll fix all your architecture problems. AutoMapper actually generates crappy auto-generated ViewModels that will contains lots of entity properties you don't want to expose to the controller. I wish I could downvote your comment. – ken2k Nov 21 '13 at 16:26
  • 1
    Not true at all, it will only map properties that exist in your model. I am not suggesting auto generating view models based on entites. – Maess Nov 21 '13 at 16:41
  • 1
    In our project we use T4 code generation together with DataObject.Net ORM (Code first). We generate extensions to the model and completely generate the viewmodel with it. Because we have classes that can get all the metadata from the model into our templates we can generate about anything. Just to give an: example we also generate DataSources and DataModels for the Kendo UI View. We've got a second implementation for our legacy which uses LINQ to SQL. Any change in the model(s) is immediatly reflected in all layers and can be used on any view. Our ORM is the model. – Paul Sinnema Nov 21 '13 at 16:55
  • @ken2k, I wish I could downvote your comment. Nothing about AutoMapper requires you to pollute viewmodels with unwanted entity properties. This is only the case if you are trying to map viewmodels back into entities (without a ton of Ignore statements), which you should never do. – danludwig Nov 21 '13 at 18:00

4 Answers4

2

I am using Entity Framework Code-First and my POCO's need to conform to the requirements of EntityFramework. I can think of 3 areas where that impinges on the design - there may be more

  1. My navigation properties must implement ICollection<T> and must have a setter - so I cannot have a ReadOnlyCollection<T> with no setter yet

  2. If I want to lazy load then I have to mark my navigation properties as virtual. Lazy loading means that Entity Framework will generate proxy objects that inherit from the Entities, and sometimes that can intrude too, but you do not have to lazy load if you don't want to and the POCO's will remain untainted.

  3. With Entity Framework, life is easier if the POCO's have a foreign key but, again, you can make do with absent foreign keys if you wish

So my models are not part of the data access layer, just influenced slightly. And they do not need to expose anything about Entity Framework.

I can code up a new class, add or remove properties, change relationships then I can scaffold a data migration to alter the database in line with the model. That means data-access development is very easy and very fast.

Now, you are used to using the models in the entire application, and I'm sure many people do that in MVC applications. Your issue here is not with Entity Framework, it is with MVC. You should be asking the question (as you have already) Why should I use view models? and compare that to your experience with PHP.

Why don't you use ViewModels in your PHP controllers and Views? Apparently once you do, you don't go back!

So use Entity Framework to make your data access fast.

Then use automapper to make it quick to map models to viewmodels - or don't and map them yourself in code - or don't use ViewModels at all and carry on as you currently do in PHP

Community
  • 1
  • 1
Colin
  • 22,328
  • 17
  • 103
  • 197
  • An important tool in EF is the entity change tracking: once I change some value, EF tracks this change and save in DB with almost no effort, and I'm pretty sure EF consumes a lot of performace to make this accomplishment. If I use ViewModels, I won't be using this change tracking anymore, this isn't a huge waste? Now I have to search for entity that have id: X, change some property manually and save in database. Summary: more work to do, less performance, waste of a tool.. it seems that EF is made to work only with entities, mapping with my own models (viewmodel) don't feel a natural EF way – Wagner Leonardi Nov 21 '13 at 18:30
  • 1
    @Wagner, the purpose of a ViewModel is not to track pending changes to entity model state, it is to move data between a web page and controller actions (again, it is just a DTO). So no, it is not wasted, and yes, you do have to lookup the entity when you're ready to save it. It is not the responsibility of a ViewModel to automate any database stuff for you. – danludwig Nov 21 '13 at 18:37
  • @danludwig I know, that's why I'm saying that using ViewModel instead Entities is a waste, because I'm not using a tool that EF provides me to be more easier and faster, and that's why I'm saying that doing this don't feel natural. Why EF provides me this tracking change , and DbContext is EF hearth, and I won't use it? Why did it was made for so? – Wagner Leonardi Nov 21 '13 at 19:09
  • @Wager I am not following you at all here, perhaps something is being lost in translation. You don't use ViewModels instead of Entities. You use both of them, but for different purposes: ViewModels to move the data between a web page and a controller action, and Entities to move data between the controller action (or a lower layer) and the database. That's where AutoMapper comes into play, to transfer data between ViewModels and Entities (or possibly some Command/Query/other service DTO layer) *in the controller action method body*. – danludwig Nov 21 '13 at 19:36
  • @danludwig I updated my question about AutoMapper usage. I can't use AutoMapper. I know cleary what you're talking about ViewModels, the problem is the effort to maintain the Entity <-> ViewModel without the automapper.. and about losing EF tracking, 'cause once I update my ViewModel I have to update manually Entity in database. A lot of work while EF suposed to do all automatically (and it does in a single layer application). – Wagner Leonardi Nov 21 '13 at 21:07
  • @Wagner once the data goes into a ViewModel it's headed out over the web. If you use your Entity instead it is no longer tracking anyway – Colin Nov 22 '13 at 09:05
1

When all you have is a hammer, then everything will look like a nail.

Don't think as EF, or any ORM, as something that's designed to make everything easier and faster. It is a tool for a job. The role of an ORM is to bridge the gap between a physical relational model (SQL) and a conceptual object model (CLR). It makes moving data between the heap and tables easier & faster, and that is all.

Say what you want about AutoMapper, but again, it is a tool for a job. The idea of a Data Transfer Object has been around even longer than ORM's. In fact, that's really what your entity classes are -- DTO's. They separate concerns between one layer of your application (the conceptual object model) and another layer (the physical relational model). All AutoMapper does is simplify DTO code. It is not a "quick fix", it is a tool with a purpose.

Now if you want to use your entity DTO's all the way to the externally-facing surface of your application, you can do that. It's probably not a good idea, but there is nothing stopping you. But if you do do this, then my question to you is, where is the separation between layers in the "Layered Architectures" you are talking about?

Reply to comment:

I suppose the question you need to answer for yourself is, which is more important: to write code quickly and easily, or to have a layered architecture that can be sanely managed as new requirements force it to grow. No doubt there is more fingerwork involved in a layered architecture, unless you are using T4 to generate code like @Paul Sinnema. The shortest distance to a story implementation is often an ASP.NET WebForm with a SqlDataSource.

If you were allowed to use AutoMapper, it could help with a lot of tedious code writing. Don't blame EF for this, blame whoever is making you do EF plus MVC minus AutoMapper.

danludwig
  • 46,965
  • 25
  • 159
  • 237
  • I can't use AutoMapper because I'm not allowed to use third-party products in some projects. Also, I agree that's extremely wrong to use the entities in my whole application, but working with EF in the 'right' layers is consuming more time than using Stored Procedures. So I'm guessing that I'm doing something wrong and maybe have a better and faster way to do this job. Plus, the 'big deal' about EF is to track changes in my entities, and if I use another class, this isn't tracked , right? So i'm wasting EF – Wagner Leonardi Nov 21 '13 at 18:09
0

Using Entities as models can have unintended consequences including data loss. Considering the following example:

In sprint 1 I create a widget entity and a view to create and edit new widgets (lets call this View1). widget has the following properties: ID, prop1, prop2

In sprint 2 There is a story to add prop3 and prop4 and to create a new page where you edit those properties. Assume a different dev than in sprint 1 gets this story. If this dev does not add the prop3 and prop4 properties to View1 as hidden fields, when someone uses View1 to edit the widget, the prop3 and prop4 properties will get set to null.

Where as, if View1 and this new view had their own ViewModels which were mapped into the widget entity, this would not happen.

Maess
  • 4,118
  • 20
  • 29
  • This would not happen if you use code first. The changes would be committed to source control. I do agree that using the EF with source control is a mess. Merging of the XML has it's drawbacks that's why we use DataObjects.Net which uses pure C# classes to describe the model. Merging of C# code is no problem. – Paul Sinnema Nov 21 '13 at 17:00
  • This would happen with code first. Since both views use Widget as a model, if View one updates Widget and prop3 and prop4 are null they will be set to null, and they will be null since they are part of the model but do not appear on the view (no controls or hidden fields) the standard model binder will set them to null. – Maess Nov 21 '13 at 17:56
0

What I tend to do is the entities are my domain model, acted upon by the services within the application. I create complete separate classes for my viewmodel, to maintain the SOC between the 2.

Phil Boyd
  • 380
  • 3
  • 17
  • Yes, and I'm doing this in the same way. But like I said, in PHP I don't need to maintain two "environments", this is hard and consumes a lot of time, also the big deal of EF is to track changes, and if I just change ViewModel it doesn't get changed in DB. I'm searching in a solution for this: make work easier and use all EF advantages. – Wagner Leonardi Nov 21 '13 at 18:14
  • I think it's a very dangerous path to go down trying to combine the 2. – Phil Boyd Nov 22 '13 at 15:33