What is the "database model"? Is this an appropriate class to contain methods for reading and writing methods to the database?
After studying MVC a bit, I'm confident in saying that the Model portion is where I should be communicating with the database. I currently have my entity classes (such as the classic "Person") and a class called DatabaseModel which has public methods for executing SQL queries on the database.
Then, in other classes in my controller, I create a DatabaseModel object, and execute the public methods within that class to retrieve SQL query results.
Am I approaching this correctly? Also, on a side note, I have a feeling this DatabaseModel class is going to become very large. Is there a good strategy for breaking this up (possibly for related queries). I thought of dividing it into partial classes in C#, but that's my best guess right now.
Database models is the mapping structure for your database schema, in such case it will be the Entity class, so back to definition; that been said. In order to interact or query your Database you have 2 common patterns which you can follow, DAO pattern, and simply this is a class which will contain the main query operations for each entity CRUD operations or [ Save , Update and Delete ], that means if you have PersonEntity you should have PersonDAO.
The second pattern is Repository pattern, and I think you will have that in any powerful framework, and will support you with ready CRUD methods to use it directly with no need to write the definition code for each operation, unlike DAO pattern.
Speaking about code quantity in each class, actually it depends, however you should follow clean code strategies, that is for any class you shouldn’t do everything to find yourself having more than 400 lines of code, this as example.Unless you really need to have this.
After studying MVC a bit, I'm confident in saying that the Model portion is where I should be communicating with the database. I currently have my entity classes (such as the classic "Person") and a class called DatabaseModel which has public methods for executing SQL queries on the database.
Actually I disagree, this is the misconception I've had when I started. To me, M is the the mapping to the database, it is the database itself, using either entity framework or some other framework of your choice, so you can create a database using code first approach without ever touching SQL.
Then, in other classes in my controller, I create a DatabaseModel object, and execute the public methods within that class to retrieve SQL query results.
This should be a job for your repository, where you retrieve SQL query results, please keep in mind that this is not the actual controller.
Am I approaching this correctly? Also, on a side note, I have a feeling this DatabaseModel class is going to become very large. Is there a good strategy for breaking this up (possibly for related queries). I thought of dividing it into partial classes in C#, but that's my best guess right now.
You are almost there, what you have right now is the Model(Database mapping), the Repository(where you execute and retrieve data), but you are missing the Controller(where you get the repository using dependency injection and do the actual work, for example mapping the data to your ViewModel), your ViewModel(where you map the data so you only get and send what you need from the data to the view, this might seem like pointless at first, why can't we just send the data to the view, but it comes with many benefits, for example, you are only dealing with what you actually need, you can verify user input(client side validation) before mapping it back to data etc), and then finally the View(your display).
So to me, MVC is just a standard, it doesn't mean you only have the Model View and Controller, I never liked the acronym, it causes too much confusion at first, to me, it should be: M(Model, the database mapping)C(Controller)VM(ViewModel)V(View), and also the repository between the Model and the Controller, but let's leave that out because it's a personal preference thing, most of the time people are just confused about the difference between the Model and the ViewModel.
Related
I'm working with repositories and one thing I'm really working hard on is to make things as most decoupled as they can. So, if tomorrow we change from relational databases to something else, like NoSQL and things like that we are good to go, we just have to change our DAL.
I've been trying to find out how to implement the SaveChanges method in my WebAPI controller without needing to use the EFContextProvider. I've found then the Breeze NoDb sample, however this sample uses the Breeze ContextProvider in the repository. This is something that troubles me because Breeze is a JS library, so it is something about the presentation of my application. In that case, making the repository use a component from Breeze will couple the DAL and the presentation, something I don't want to do.
Searching again for how to implement SaveChanges without EF I've found this question where there's one very good answer telling how to convert the SaveBundle to a SaveMap and then tell to use this to implement the saving logic. However I'm stuck in this method because the entries of the SaveMap give just one Type object and the EntityInfo, so I don't see how to use this with my repositories.
So, how to deal with SaveChanges without to refer to EFContextProvider and without coupling the repositories with the ContextProvider?
Are you planning to switch from SQL Server to NoSQL database? why don't you want to do that just now? How often are you planning to switch backing storage? Probably not often, if ever.
I found that database switch, especially from SQL to NoSQL is a big shift in paradigm. In one of my application I've gone through conversion from SQL to RavenDb. Despite of having everything decoupled and with using Repositories everywhere, I still had to rewrite most of the application storage logic.
What you are trying to do - you are not going to need it. So stop making life hard for yourself and get on with implementing features.
The ContextProvider does the work of converting the JObject (which Json.NET gives you in the SaveChanges method), into real, typed .NET objects. The EntityInfo object that the ContextProvider creates for each entity contains the entity object itself, as well as the entityAspect properties that it got from the client: the EntityState (Added, Modified, or Deleted), the original values of all changed properties, and the temporary values for any auto-generated keys. This is the information that you would need to save the entities yourself. The "SaveMap" just organizes them by Type for convenience, but you can manipulate them however you like.
As described in the post you referenced, you could proceed by using a ContextProvider just to convert the JObject to entities, then pass those entities to the appropriate repositories. Your repositories don't need to know anything about the ContextProvider.
Breeze offers an NHibernate provider that you can look at that shows how to talk to a non EF backend that is still a .NET server. The ContextProvider is a convenence that makes implementing any .NET provider substantially easier, but it is by no means a requirement.
As for NoSQL you should take a look at the breeze Node provider and MongoDB sample which is hosted in NodeJs ( which shows that the ContextProvider is obviously not a requirement).
We also expect to have a Breeze server implementation written in Java in the near future, which again has no "ContextProvider" requirement.
How reusable are the results of using EF?
Currently, I use stored procedures for 100% of my data access. The main reason I may be looking to do things differently for my newest project is for maintainability: adding an attribute to a table means manually altering dozens of stored procedures. If I understand EF correctly, I should be able to add an attribute to an Entity in my EF model, and then ask EF to update my CRUD methods for me. awesome.
However, there is one thing holding me back: reusability. I like that I can make the SP's for a given database once, and be done with them; I can make 12 applications that all use that database and getting that data will be as easy as calling the correct SP.
Will the same be true if I switch to a more EF-centric approach?
Can I import an Existing EF Data Model and have it work without too much trouble?
Can I make it so that I alter the Data Model once, and that change is felt across all applications?
Ad1. You can easily reuse complex EF queries if you follow the Repository pattern. Repositories are where you encapsulate your data access and, yes, repositories are easily reused between different modules/applications.
(not that you can't reuse code without Repositories! Repositories are just a common way of doing it for data access layer)
Ad2. I am not sure what you mean by "import existing EF model" (import where?) but usually EF models are straightforward and can be reused
Ad3. Just have your model in a separate assembly.
A real benefit to using EF is getting away from stored procedures.
The problem that exists with using stored procedures for all your data access is that you are forced to put business logic into your data layer.
Check out Should the data access layer contain business logic? While its not true in every case, generally keeping your business logic in your business layer gives you better separation of concerns.
I have an EF project that I use as the data layer for several applications. This allows me to change it once and have all the other projects get the benefits. Granted, sometimes supporting code needs to be changed in these other projects, but you'd have that same problem in a stored procedure model as well.
Any N-tier design would solve this problem by simply creating a class (in a class library) that understands how to access the data by using entity framework. Then any applications that want to access the data uses the class library, configure a connection string in the app.config or web.config and you're done.
I am currently working on an MVC 4 application. I am planning to implement a command query seperation pattern to enhance performance and the structure of the application. I am happy with my commands - which map my view models to my entities use then use nhibernate to save my data.
The commands and queries will be running off the same database.
I am a bit unsure of the best approach to manage my queries. In my last project I used Stored procedures for all of my reads/queries, then used automapper to map my IDataReaders to my ViewModels. This worked ok but the main problem was the turn around time of writing the stored procedures and also when the domain model changed the stored procedures got out of sync.
Therefore, ideally I would like something that auto generated the views or sprocs from my view models. But realistically, I cannot see a way of doing this. As the Sprocs/Views need some knowledge of potentially more that one table. So simply reflecting on the View model properties would not be enough.
I could auto generate a table for each view model, read this during development, then once the domain was stable and before we went to test convert these to views/sprocs?
So I guess what I am asking is:
Has anyone managed to solve the sproc/view auto generation problem I described above? (this would be my favourite outcome!) Or even better has designed a much more graceful solution!
Or is it more sensible to only implement raw ADO reads where they are absolutely necessary - i.e searches, and there dispense with the need for lots of sprocs/views.
But then still separate out my queries into a separate channel (but inside some of them they use NHibernate, whilst others use my ADO reader).
(p.s I have looked at the other stackoverflow CQS related questions and I hope mine is different enough to warrant this question)
What do stored procedures solve for you? Why can't you use NHibernate for reads too? Are the queries NHibernate produces that bad?
If performance of reads is crucial for you, and the shape of your viewmodels is very different from how you store your model - making the denormalization process to a viewmodel too heavy to do on the fly, you might have to consider completely splitting reads and writes.
When you write something, you can raise an event - often done asynchronously - on which subscribers listening can store data on the readside in such a way that it's optimal for reads (close to the shape of your viewmodel). This would make querying really fast.
Since a picture says more than a thousand words..
You can read a good introduction to CQRS here.
So my programming background is very self-taught and sporadic. I am working on an MVC4 project and am trying to focus on best practices rather than just functionality.
The general sense of the project is a report generator. So I am trying to understand what exactly Domain Model vs View Model are, and how they related to the models used for CodeFirst Entity Framework. Any tips are appreciated.
From my understanding, let's say my Report object has multiple properties, but for the view I only want a user to be able to edit certain properties, then the ViewModel would be something that maps between the Report object and the user input?
Sounds like you've got the right idea. A ViewModel is the View representation of the domain entity. This can be applied to both data coming in and data going out of the model.
But, the extra layer (and mappings) also increase complexity of the code. You now need a view model class, a mapper class, and a domain entity (EF). So, if you can build what you need without this extra layer, then keep it simple. Domain models and domain modeling should only be used for a business domain that is significantly complex.
Yes your understanding is correct.
View model is data object used by your view. It contains properties necessary either for showing some data to user or collecting data from user. Those properties doesn't necessarily be only data. For example you can have some properties used to control if any field in the input form will be enabled or disabled.
Domain model on the other hand is object used for your logic and persistence. Again it doesn't necessarily contain only persisted properties. There can be other properties computed from persisted properties and there can be also methods working on top of properties.
In some very simple scenarios view model and domain model can be represented by the same object.
This is what I've seen in a few examples, what I've used for the last couple years and feel comfortable with, and was also the pattern already in use by a preexisting MVC team when I came into my most recent job.
Basically entity framework, or whatever ORM your using, will have Entity classes. These are either simple POCO's or something heavier with some ORM's. The goal is for the relationships between entities to closely resemble reality, and as such they are in a way your "Domain models". Either way, you will often find that you're view needs to either flatten properties from child/parent objects, or as you mentioned, only display certain fields.
Often times you will also need additional fields on the view model. For example, the options for a dropdown list, as these aren't part of the entity(only the foreign key that indicates which item is selected is in the entity, but not the list of items from which the user can select).
So unless your view is simple enough to be able to use the #model of your EF entity, often times you may need a ViewModel(VM) class. Some people have a different VM for each view. I personally try to reuse my VMs. Usually a PersonSummaryViewModel which is just a few fields good for things like select lists or indexes where space is limited and I will only display important fields, and a PersonViewModel which are all the fields from the entity, as well as fields for items for dropdown lists(but when used on a readonly page those are simply left null).
Personally I like to name things PersonVM and PersonSummaryVM but others prefer more verbose naming of PersonViewModel. EF will give your entities names like Person, but I've seen other ORM frameworks suffix all of the classes with Entity so you have PersonEntity. I've come to be fond of the Entity suffix personally.
If your database is well designed, it is likely that your entity classes are pretty close to what some would consider your domain model.
We have classes that expose static methods which we call to retrieve data. The controllers have little to no database code in them, and instead all of that are in static methods like PersonModelFactory.GetList(), PersonModelFactory.GetSingle(int id), .Save(PersonVM person) which are responsible for querying the database, and populating the data from the entities into the view models, and then returning a view model. These methods also perform certain validation(beyond what basic things you can do with data annotations on your view models), and other business logic IF it is something that should occur in tandem with whatever database modification is occurring. There's more to the implementation details involving interfaces and generic parameters that are aimed at making these methods very reusable but it is a little complicated for the scope of this post. We've actually successfully reused these classes from both web forms and MVC, so they've proved there re-usability. Some people wouldn't like the fact the DB access, mapping, and business logic/validation occurs in the same layer, but since the DB modification shouldn't occur unless validation passes, we felt it was important for these things to be atomic and mutually dependent.
It is probably more common for people to use the "repository pattern" for database access layer with MVC, and there are even scaffolding for MVC to generate these classes for you. However, these generally won't handle mapping or business logic.
Either way, the main goal is reuse and minimizing the clutter in your controller actions. Before adopting the factor pattern I mentioned, I found my controllers becoming cluttered. I saw opportunities for code to be reused between actions, and thus I was creating private methods in the controller. I really like the factory pattern the team I'm on now uses alot more.
You will definitely find many variations of how people use view models and repositories.
I cannot recall having seen any articles or examples that speak specifically about "domain models" in the context of MVC. IMO domain modelling is part of the requirements gathering process, and then the design of the database/entity framework will reflect the results of those findings. Given limitations of time/resources/complexity you may simplify the domain model. There are frameworks that deal with things like domain languages and what not, I don't think that kind of thing is very common.
Before there were ORMs, there were people doing alot of mapping manually between the database layer(consisting of command objects running SQL), into "business objects" which were often POCOs, basically what you have as EF entities, but sometimes they had some business validation/logic incorporated somehow. Now I don't hear people talk about "business objects" hardly ever because the purpose that layer served has mostly been replaced with EF, and the business logic is either in controller actions or in some other service layer.
Over the years, one thing is certain, what "view model", "business model", "entity", and "domain model" mean to different people will vary.
I seem to be missing something and extensive use of google didn't help to improve my understanding...
Here is my problem:
I like to create my domain model in a persistence ignorant manner, for example:
I don't want to add virtual if I don't need it otherwise.
I don't like to add a default constructor, because I like my objects to always be fully constructed. Furthermore, the need for a default constructor is problematic in the context of dependency injection.
I don't want to use overly complicated mappings, because my domain model uses interfaces or other constructs not readily supported by the ORM.
One solution to this would be to have separate domain objects and data entities. Retrieval of the constructed domain objects could easily be solved using the repository pattern and building the domain object from the data entity returned by the ORM. Using AutoMapper, this would be trivial and not too much code overhead.
But I have one big problem with this approach: It seems that I can't really support lazy loading without writing code for it myself. Additionally, I would have quite a lot of classes for the same "thing", especially in the extended context of WCF and UI:
Data entity (mapped to the ORM)
Domain model
WCF DTO
View model
So, my question is: What am I missing? How is this problem generally solved?
UPDATE:
The answers so far suggest what I already feared: It looks like I have two options:
Make compromises on the domain model to match the prerequisites of the ORM and thus have a domain model the ORM leaks into
Create a lot of additional code
UPDATE:
In addition to the accepted answer, please see my answer for concrete information on how I solved those problems for me.
I would question that matching the prereqs of an ORM is necessarily "making compromises". However, some of these are fair points from the standpoint of a highly SOLID, loosely-coupled architecture.
An ORM framework exists for one sole reason; to take a domain model implemented by you, and persist it into a similar DB structure, without you having to implement a large number of bug-prone, near-impossible-to-unit-test SQL strings or stored procedures. They also easily implement concepts like lazy-loading; hydrating an object at the last minute before that object is needed, instead of building a large object graph yourself.
If you want stored procs, or have them and need to use them (whether you want to or not), most ORMs are not the right tool for the job. If you have a very complex domain structure such that the ORM cannot map the relationship between a field and its data source, I would seriously question why you are using that domain and that data source. And if you want 100% POCO objects, with no knowledge of the persistence mechanism behind, then you will likely end up doing an end run around most of the power of an ORM, because if the domain doesn't have virtual members or child collections that can be replaced with proxies, then you are forced to eager-load the entire object graph (which may well be impossible if you have a massive interlinked object graph).
While ORMs do require some knowledge in the domain of the persistence mechanism in terms of domain design, an ORM still results in much more SOLID designs, IMO. Without an ORM, these are your options:
Roll your own Repository that contains a method to produce and persist every type of "top-level" object in your domain (a "God Object" anti-pattern)
Create DAOs that each work on a different object type. These types require you to hard-code the get and set between ADO DataReaders and your objects; in the average case a mapping greatly simplifies the process. The DAOs also have to know about each other; to persist an Invoice you need the DAO for the Invoice, which needs a DAO for the InvoiceLine, Customer and GeneralLedger objects as well. And, there must be a common, abstracted transaction control mechanism built into all of this.
Set up an ActiveRecord pattern where objects persist themselves (and put even more knowledge about the persistence mechanism into your domain)
Overall, the second option is the most SOLID, but more often than not it turns into a beast-and-two-thirds to maintain, especially when dealing with a domain containing backreferences and circular references. For instance, for fast retrieval and/or traversal, an InvoiceLineDetail record (perhaps containing shipping notes or tax information) might refer directly to the Invoice as well as the InvoiceLine to which it belongs. That creates a 3-node circular reference that requires either an O(n^2) algorithm to detect that the object has been handled already, or hard-coded logic concerning a "cascade" behavior for the backreference. I've had to implement "graph walkers" before; trust me, you DO NOT WANT to do this if there is ANY other way of doing the job.
So, in conclusion, my opinion is that ORMs are the least of all evils given a sufficiently complex domain. They encapsulate much of what is not SOLID about persistence mechanisms, and reduce knowledge of the domain about its persistence to very high-level implementation details that break down to simple rules ("all domain objects must have all their public members marked virtual").
In short - it is not solved
(here goes additional useless characters to post my awesome answer)
All good points.
I don't have an answer (but the comment got too long when I decided to add something about stored procs) except to say my philosophy seems to be identical to yours and I code or code generate.
Things like partial classes make this a lot easier than it used to be in the early .NET days. But ORMs (as a distinct "thing" as opposed to something that just gets done in getting to and from the database) still require a LOT of compromises and they are, frankly, too leaky of an abstraction for me. And I'm not big on having a lot of dupe classes because my designs tend to have a very long life and change a lot over the years (decades, even).
As far as the database side, stored procs are a necessity in my view. I know that ORMs support them, but the tendency is not to do so by most ORM users and that is a huge negative for me - because they talk about a best practice and then they couple to a table-based design even if it is created from a code-first model. Seems to me they should look at an object datastore if they don't want to use a relational database in a way which utilizes its strengths. I believe in Code AND Database first - i.e. model the database and the object model simultaneously back and forth and then work inwards from both ends. I'm going to lay it out right here:
If you let your developers code ORM against your tables, your app is going to have problems being able to live for years. Tables need to change. More and more people are going to want to knock up against those entities, and now they all are using an ORM generated from tables. And you are going to want to refactor your tables over time. In addition, only stored procedures are going to give you any kind of usable role-based manageability without dealing with every tabl on a per-column GRANT basis - which is super-painful. If you program well in OO, you have to understand the benefits of controlled coupling. That's all stored procedures are - USE THEM so your database has a well-defined interface. Or don't use a relational database if you just want a "dumb" datastore.
Have you looked at the Entity Framework 4.1 Code First? IIRC, the domain objects are pure POCOs.
this what we did on our latest project, and it worked out pretty well
use EF 4.1 with virtual keywords for our business objects and have our own custom implementation of T4 template. Wrapping the ObjectContext behind an interface for repository style dataaccess.
using automapper to convert between Bo To DTO
using autoMapper to convert between ViewModel and DTO.
you would think that viewmodel and Dto and Business objects are same thing, and they might look same, but they have a very clear seperation in terms of concerns.
View Models are more about UI screen, DTO is more about the task you are accomplishing, and Business objects primarily concerned about the domain
There are some comprimises along the way, but if you want EF, then the benfits outweigh things that you give up
Over a year later, I have solved these problems for me now.
Using NHibernate, I am able to map fairly complex Domain Models to reasonable database designs that wouldn't make a DBA cringe.
Sometimes it is needed to create a new implementation of the IUserType interface so that NHibernate can correctly persist a custom type. Thanks to NHibernates extensible nature, that is no big deal.
I found no way to avoid adding virtual to my properties without loosing lazy loading. I still don't particularly like it, especially because of all the warnings from Code Analysis about virtual properties without derived classes overriding them, but out of pragmatism, I can now live with it.
For the default constructor I also found a solution I can live with. I add the constructors I need as public constructors and I add an obsolete protected constructor for NHibernate to use:
[Obsolete("This constructor exists because of NHibernate. Do not use.")]
protected DataExportForeignKey()
{
}