Let's say I have two tables in a database: projects and users. I create two models, that extend Zend_Db_Table_Abstract: Model_DbTable_Users and Model_DbTable_Projects.
Now, is it a good pattern to create an instance of Model_DbTable_Projects inside the Model_DbTable_Users class ? In other words: is it OK to put any logic in this model, or should I create another class, that uses Model_DbTable_Users and Model_DbTable_Projects?
I use to put all the logic in models, that extend Zend_Db_Table_Abstract, but in large projects it can make code very unclean. So, can you give me any advice on models architecture(links on articles would be great!).
I was the project lead for the Zend Framework project through version 1.0. My contributions were mainly in the Zend_Db component.
I frequently advise that people should use the Domain Model pattern and avoid the Anemic Domain Model antipattern. Remember that a Table is not a Model.
Your Model is a class (extending no base class) for code that encapsulates your business logic. The relationship between a Model and a Table isn't IS-A, it's HAS-A (or HAS-MANY). The Model treats database persistence as an implementation detail. The consumer of a Model should have no clue about your database structure (this allows you to change database structure without changing the Model's interface).
I'm basically repeating the answer I gave to Models in the Zend Framework.
Here is some more reading:
http://weierophinney.net/matthew/archives/202-Model-Infrastructure.html
http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html
http://n4.nabble.com/Another-Model-Design-Thread-td670076.html
Related
I'm aware that copying entity classes and properties into DTOs is considered anti-pattern, so by Exposed domain model pattern the same #Entity can be used as both database entity class, and DTO for service and MVC layer. (see here https://codereview.stackexchange.com/questions/93511/data-transfer-objects-vs-entities-in-java-rest-server-application)
But suppose we have microservice architecture where the same set of properties is used as entity in one project with persistence, and as DTO in another project which uses the first one as a service. What's the proposed pattern in such a situation?
Because the second project doesn't need #Entity related functionality, and if we put that class in shared library, it will be tied unnecessary to JPA specific APIs and libraries. And the alternative is to again use separate DTO classes anti-pattern.
When your requirements for a DTO model exactly match your entity model you are either in a very early stage of the project or very lucky that you just have a simple model. If your model is very simple, then DTOs won't give you many immediate benefits.
At some point, the requirements for the DTO model and the entity model will diverge though. Imagine you add some audit aspects, statistics or denormalization to your entity/persistence model. That kind of data is usually never exposed via DTOs directly, so you will need to split the models. It is also often the case that the main driver for DTOs is the fact that you don't need all the data all the time. If you display objects in e.g. a dropdown you only need a label and the object id, so why would you load the whole entity state for such a use case?
The fact that you have annotations on your DTO models shouldn't bother you that much, what is the alternative? An XML-like mapping? Manual object wiring?
If your model is used by third parties directly, you could use a subclassing i.e. keep the main model free of annotations and have annotated subclasses in your project that extend the main model.
Since implementing a DTO approach correctly, I created Blaze-Persistence Entity Views which will not only simplify the way you define DTOs, but it will also improve the performance of your queries.
If you are interested, I even have an example for an external model that uses entity view subclasses to keep the main model clean.
Thank you for the answers, but emphasize in the question is on microservice (MS) architecture and reusing defined entity POJOs from one MS in another as POJOs. From what I've read on microservices it's closely related to another question - should MSs share any common functionality and classes at all, or be completely independent? It seems there is no definite agreement on it, and also no definite answer, or widely accepted pattern, to this.
From my recent experience here is what I adopted, and it works well so far.
Have common functionality across MSs - yes, in form of a commons project added as dependency to all MSs, with its dependencies set as optional. Share entity classes (expose them in commons) - no.
The main reason is that entity classes are closely related to data store for particular MS. And as the established rule is that MSs shouldn't share data stores, then it makes sense not to share entity classes for those data stores. It helps MSs to be more independent, and freedom to manage their data store in their own way. It means some more typing to add additional DTO classes and conversion between them, but it's a trade-off worth taking to retain MS independence. Reasons Christian Beikov and Maksim Gumerov mentioned apply as well.
What we do share (put in commons) are some common functionality and helper classes (for cloud, discovery, error handling, rest and json configuration...), and pure DTOs, where T is transfer between MSs (rest entities or message payloads).
I am working on a Web Application using ASP.Net MVC 4 3-Tier Architecture and I am stuck at certain points. I know here exist similar threads but none were clear enough. I have already created the needed layers which are UI(MVC4 project), BLL- Business Logic Layer(library class), BOL- Business Object Layer(library class that contains ADO.net) and DAL- Data Access Layer (library class).
Layer dependencies are as follows:
UI depends on BOL and BLL
BLL depends on BOL and DAL
DAL depends on BOL
I want you to correct me if I am wrong in the following. The BOL is the master reference layer which exchanges raw dB records with DAL then sends them to BLL which is responsible for any logical computations then gets the updated records and sends them to the controller in the UI.
Knowing the above,
Where should we place the CRUD functions?
Where and why should we create a class for declaring (plus set and get) the useful database fields?
What exactly should we put in the ViewModel folder; in other words since we have already defined the variables in the previous step and in the Entity then does it add any value to keep the Model folder?
Thank you in advance.
Can't be unambiguously correct answers on these issues, so any answer should be evaluated simply as an opinion. Here are my answers:
Where should we place the CRUD functions? CRUD is a frequent pattern at different levels. Hi-level Repository provides similar methods, as a low-level Table Gateway.
Where and why should we create a class for declaring (plus set and get) the useful database fields? These classes are usually simple Data Transfer Objects (DTO) or slightly more complicated Active Records. In accordance with the Dependency Inversion Principle the interface for these classes should provide the Business Logic Layer, and implementation should provide the Data Access Layer. Since DTO is very simple classes, they can be provided "as is" without interface/implementation separation.
What exactly should we put in the ViewModel folder; in other words since we have already defined the variables in the previous step and in the Entity then does it add any value to keep the Model folder? In theory entities should be our models; but in practice it's often not the case. F.e. in ASP.NET MVC models should provide not only the value of drop-down field, but also all possible values; so it requires the separate model class.
The result may be that you have three or four very similar classes at different levels of the application. Of course, it's not very good, so Aspect Programming may be applied in this case.
I have a domain model architecture in which my domain/business objects were created based on the problem domain and independent of any knowledge of the physical data model or persistence structures. So far I'm on track because it's perfectly acceptable and often the case that there is an impedance mismatch between the domain model and the data model. A DBA created the database for getting the data they required, but it does not encapsulate the applications entire domain model or design.
The result - I have my own set of domain model objects. However all of the fields that need to be persisted do exist somewhere or another within my domain model, but not necessarily in the shape that my auto generated .edmx POCO entities have them. So I have all the data, it's just not in the perfect shape exactly like the tables in which auto generated POCO entities are created from.
I have seen a few posts on this topic like converting POCO entity to business entity and Entity Framework 4 with Existing Domain Model that make statements like the following:
"Create the entities in your entity data model with the same names as
your domain classes. The entity properties should also have the same
names and types as in the domain classes"
What!? No way, why should I have to make my domain model be reshaped to POCOs that are modeled exactly after the data model / table structure in the database? For example - in my case of having 5 given properties, 2 might be in class 'A' and 3 in class 'B', whereas a auto generated POCO class has all 5 in its own class 'A'.
This is the entire point, I want separation of my object model and data model but yet still use an ORM like EF 5.0 to map in between them. I do not want to have to create and shape classes and properties named as such in the data model.
Right now my .edmx in EF 5.0 is generating the POCO classes for me, but my question is how to dissolve these and rewire everything to my domain objects that contain all this data but just in a different shape?
By the way any solution proposed using a Code First approach is not an option so please do not offer this. I need some guidance or a tutorial (best) using EF5 (if possible because EF4 examples are always inheriting POCOs from ObjectContext) with wiring up my own business objects to the .edmx.
Any help or guidance is appreciated, thanks!
This sounds like exactly the use case of Entity Framework. I am making a few assumptions here. First that when you make this statement:
"I have a domain model architecture in which my domain/business objects were created based on the problem domain and independent of any knowledge of the physical data model or persistence structures."
That you mean this domain was created in the EF designer? But then you say:
"However all of the fields that need to be persisted do exist somewhere or another within my domain model, but not necessarily in the shape that my auto generated .edmx POCO entities have them."
This sounds to me like my first assumption is incorrect.
Next, you dismiss code first? If your domain model/business objects are code based and you want to persist them to a relational database, that is exactly the use case for code first. You have the code, now you need to create your DbContext and map it to your physical model.
However you dismiss that... so some thoughts:
If you have a domain model of code based business objects and you have an EDMX that is used for other things I think you would want to create a repository layer that uses something like auto mapper or manual projections to query your Entities and return your business objects.
If you have a domain model of code based business objects and you have an EDMX that is not used for other things other than persisting your business objects I would say that you need to express your domain in an EDMX and then map it onto your existing database. This is really the use case for an ORM. Having two domain models and mapping from one model to the other where one model matches your domain and one matches your database is adding an extra un-needed layer of plumbing.
The latter approach above is what is called "Model First" in EF parlance. There are several articles written about it although the bulk of them just generate the db from the model. You would not do that step, rather you would map your entities onto your existing database.
The basic steps for this are to "update from the database" not selecting any of the db objects (or entities would be created). Or, you can take your exiting .edmx in the designer (which is sounds like you have) and modify the entities to match your business domain. Or just delete all the entities in your EDMX model, create your entities as you want them, and then map them all.
Here is a jing I made where I use the EF Designer to bring in the model store (the only way to do this is to allow it to generate entities) and then delete the entities allowing the Store information to stay by clicking NO when it asks if you want to delete the table info.
http://screencast.com/t/8eiPg2kcp
I didn't add the POCO generator to this, but if I did it would generate the Entities in the designer as POCO classes.
The statement quoted above is not suggesting that you rewrite your domain objects to match your pocos, it is suggesting that you update the edmx to match your domain model.
In your example you could create an entity in your edmx that maps all 5 properties from both tables and EF will manage the mapping to and from the single generated Poco onto your tables.
Of course this means that you then have duplicate domain objects and pocos, meaning you would either have to manually convert your domain objects to pocos when interacting with EF,
or you could define your domain data objects as interfaces and provide partial implementations of the pocos that essentially identify each poco as being a concrete implementation of a domain object.
There are probably several other ways to skin this particular cat, but I don't think that you can provide predefined c# objects for use in an edmx.
One approach might be to select into a ViewModel (suited to your particular business logic) and automatically map some data from the context into it like so https://stackoverflow.com/a/8588843/201648. This uses AutoMapper to map entity properties from an EF context into a ViewModel. This won't do everything for you, but it might make life a bit easier. If you're unhappy with the way this occurs automatically, you can configure AutoMapper to do things a bit differently (see Projection) - https://github.com/AutoMapper/AutoMapper/wiki/Projection
You might know this already, but its also possible to automatically generate POCOs from your EDMX using t4 - http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d. If you define the templates to generate partial classes, you can then have another partial class with your custom properties for that POCO. That way you can have most properties automatically populated, but have other custom properties which you populate with custom rules from your context/repository. This takes a lot of the monotony out of generating these, and you can then focus on reshaping the data using the above technique.
If you're seriously unhappy with both, you could always map a stored procedure to get the exact field names that you want automatically without needing to stuff around. This will of course affect how you work with the data, but I have done it before for optimisation purposes/where a procedure already existed that did exactly what I wanted. See http://msdn.microsoft.com/en-us/data/gg699321.aspx
I'm new to the MVC way of developing applications and for the most part am enjoying. One thing I'm a bit confused about is the use of the Entity Framework. The EF usually (at least in my experience) defines multiple tables and relationships through the .edmx table. A couple of questions:
Why would I define a separate class file for a specific table if EF is building all of the classes that I need in the background?
From some of the validation approaches that I've seen, they want to define validation logic in the class related to a model for a table. If I'm using EF, will I have a .cs file describing the model and a .edmx describing that same table (in addition to its associated tables)?
If yes, how do you connect the .cs file to the .edmx definition so that CRUD flows easily from the EF?
Sorry if these seem like easy questions but I'm just trying to get my head wrapped around these fundamental concepts. Too many examples out there use only a single table where in my business, I NEVER write an application that uses a single table. There are always multiple tables in relation to each other with foreign keys. Thanks for your prompt responses.
For a tutorial that shows the use of partial classes -- in a Web Forms application but for MVC the same technique would be used -- see Adding Metadata to the Data Model in this tutorial:
http://www.asp.net/web-forms/tutorials/getting-started-with-ef/the-entity-framework-and-aspnet-getting-started-part-8
From your comment "The EF usually (at least in my experience) defines multiple tables and relationships through the .edmx table." it sounds like you are familiar only with Database First and Model First -- for an introduction to Code First and an explanation of the differences, followed by a series of tutorials with an MVC example using Code First, see this tutorial:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
Good questions, Darryl. Here are my responses to your bullet points:
Defining separate model classes that match the data models that EF creates is generally a good idea for the simple sake of separating your data access "stuff" from your business model objects that will get used throughout your app. Some people don't like this approach because it creates some amount of overhead when it comes to mapping your entities to POCOs but, if you use a tool such as AutoMapper, the overhead is minimal. The benefit lies in you creating a layer of separation between you and your (likely) evolving data model.
You could define validation logic in a buddy class (just a partial class that sits along-side your entity) but that would mean that you would be using that entity across your app and some would debate that that isn't the best idea. The alternative method, as mentioned above, is to create your own POCOs to mirror the entities that EF creates and place your validation attributes on the POCOs.
I mentioned this in the previous item but the way to do this would be to define buddy classes. Give EF buddy classes a Google and you should find plenty of examples on how to do that.
Just to add to all of this, if you choose to create POCO classes that mirror your EF entities, tools like AutoMapper can handle fairly complex relationships when it comes to mapping classes. So, if you have foreign key relationships in your data model, AutoMapper can understand that and map your POCO classes accordingly (i.e.: You have an entity that has a 1-to-many relationship and a POCO with a list of objects to mirror that relationship.)
I hope some of that helps...
I've tried to use Entity Framework 4 and POCO for my MVC 3 project. May be, I don't understand the main idea of this ORM, but the problem is following:
I added ADO .NET Entity Data Model and make model according to database.
I clicked Add Code Generation Item and added ADO .NET POCO Entity Generator.
It makes classes for every database table.
I want to add some methods to work with data (Add, Update, Delete, GetAll etc) to appropriate models.
For LINQTOSQL I added partial classes and placed them to Models. But now I can't do it because:
a) Models folder has classes with the same names, which was created by POCO.
b) If I place my partial class in the another folder, it will be another namespace - so, such classes won't be partial one.
c) If I place my code in POCO classes, it can be destroyed during update POCO.
How can I use it? Where sould I place my methods for data working?
Is the best way to make for POCO and EF the other project - http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx?
First of all you don't have to write your CRUD inside POCO,
There are many places where you can do it like in edmx.cs file or write one more layer which is called as CRUD Services which handles the Database operations using context object.
Now coming to your questions,
Create separate Models folder and place the Model classes in there.
Your Model class may like this,
EmployeeDepartmentModel
{
prop EmpList List(Emp);
prop DeptList List(Dept);
//Emp and Dept are my POCOs
}
So now I have to fill both of these list(Your CRUD question),
For that, I will Create one method in Controller class(its better to write such logic in some another library, but for time being I suggest you to create in Controller),
FillTheModel()
{
EmployeeDepartmentModel.EmpList = EDMX.GetAllEmployees;
EmployeeDepartmentModel.DeptList = EDMX.GetAllDepartments;
}
Now you can bind this model with your view.
You can place the partial classes in another folder and modify the namespace.
I agree with allisewell, but if you really want to add parts to partial classes, give files another name,
e.g. MyPoco.Part2.cs or modify t4 template to name generated files
e.g. Poco.Generated.cs