EF entities as domain-models, when decoupling them from views with view-models? - entity-framework

I'm trying to understand the best architecture for my MVC2 site.
As I have been experimenting with getting the data in and out of a database with Entity Framework, I am beginning to realize the simple domain-models I have so far constructed do not map to all the needs of my planned views. So I am considering following the accpepted answer to this question: Why Two Classes, View Model and Domain Model?.
But there seems to be redundancy with little payoff that I can perceive between the domain-models and the EF models, and I can't even hardly understand the conceptual difference. I do NOT have as a requirement the need to switch data sources down the road, and I do not forsee the need to switch my ORM solution either.
QUESTION:
If I follow this pattern then, since I am using Entity Framework, shouldn't I just use my EF entities to serve directly as the domain models? (note: I haven't thought through the "how" of that, but answers there are welcome too.) Or am I still advised to manage a separate set of domain-models?

It seems you've got some redundancy here. Reading your paragraph:
But there seems to be redundancy with
little payoff that I can perceive
between the domain-models and the EF
models, and I can't even hardly
understand the conceptual difference.
I would argue that there is no real difference between the EF Model and your Domain Model. In the projects I create, my EF Model is my Domain model.
However, my Domain model classes are not the same as my ViewModels. The Domain model class might contain data that is not interesting for the View, or maybe the view needs information that is calculated/evaluated based on information in view. A simple example might be:
public class Session // Domain model (and EF Model
{
public int Id {get; set; }
public DateTime Start {get; set; }
public int DurationInMinutes {get; set; }
}
public class SessionViewModel // The viewmodel :p
{
public DateTime Start {get; set; }
public int DurationInMinutes {get; set;}
public DateTime End
{
get
{
return Start.Add(TimeSpan.FromMinutes(DurationInMinutes));
}
}
}
In this example I'm interested in displaying the actual End-time in my View, but I have no interest in storing it in the database, as that might lead to data-discrepencies (DurationInMinutes + Start might not equal End if data is corrupted upon saving)
When I first started coding this way, I ended up doing alot of manual work mapping my Domain models to ViewModels, and back. AutoMapper changed all that :) Google it, or NuGet it and it will make your life a whole lot easier :)
Hope this helps a little. Please comment if I'm totally missing the point :)
Update to address the comment
DataAnnotations would then be applied to the ViewModel, because normally DataAnnotations denote how the data should be displayed and validated in the View.
For instance you would put the [Required] attribute on public DateTime Start {get; set;} in order for the Html.DisplayFor extensions automatically validates your HTML according to your dataannotations.
By definition (by some anyway) the Domain Model should not contain any code or logic related to your business logic. The Domain Model is simply responsible for containing the data pretty raw according to your datastore. Personally I like to put some sort of Service layer inbetween that is responsible for fetching the data and returning ViewModels, and also doing the reverse.
The ultimate goal is to avoid referencing your domainmodel directly from your controllers.
Of course, all these points has to be weighed in reference to the size of the project. It's certainly overkill to do all this just to mock up a test-site - but in any other project where you'll actually be deploying something that might scale, expand or otherwise change, it's a good practice to get used to, as it seriously increases your ability to do so.
Another key point to this approach is that you are forced to abstract your operations down to smaller and more managable units, enabling better and more precise unit-tests.

Related

Why Navigation Properties are virtual by default in EF

I have following POCO class being used in EF 6.x.
My question: Why is the navigation property of 'Posts' under 'Blog' entity declared as virtual?
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
If you define your navigation property virtual, Entity Framework will at runtime create a new class (dynamic proxy) derived from your class and uses it instead of your original class. This new dynamically created class contains logic to load the navigation property when accessed for the first time. This is referred to as "lazy loading". It enables Entity Framework to avoid loading an entire tree of dependent objects which are not needed from the database.
In some circumstances, it is best to use "Eager Loading" instead, especially if you know that you will be interacting with related objects at some point.
Julie Lerman really is the authority on all things Entity Framework, and she explains this process very well in her MSDN Article Demystifying Entity Framework Strategies: Loading Related Data
Eager loading with Include is useful for scenarios where you know in advance that you want the related data for all of the core data being queried. But remember the two potential downsides. If you have too many Includes or navigation paths, the Entity Framework may generate a poorly performing query. And you should be careful about returning more related data than necessary thanks to the ease of coding with Include.
Lazy loading very conveniently retrieves related data behind the scenes for you in response to code that simply makes mention of that related data. It, too, makes coding simpler, but you should be conscientious about how much interaction it’s causing with the database. You may cause 40 trips to the database when only one or two were necessary.
If you are developing a Web Application where every communication with the server is a new context anyway, Lazy Loading will just create unnecessary overhead to maintain the dynamic class for related objects that will never be loaded. Many people will disable lazy loading in these scenarios. Ultimately, it's still best to evaluate your SQL queries which EF has built and determine which options will perform best for the scenario you are developing under.

How do I handle persistence and unit of work in DDD using Entity Framework?

I'm a little overwhelmed with all of the information on DDD, unit of work, domain services, app services, etc. I'm trying to figure out how a persistence-ignorant domain model ultimately gets persisted, specifically in the context of unit-of-work and Entity Framework. Let's say I have an Order aggregate root, which I am attempting to keep in my persistence-ignorant domain model (the core of my architectural onion):
public class Order : EntityBase
{
public int Id { get; private set; }
public int MarketplaceId { get; private set; }
public int CustomerId {get; set;}
public List<OrderItem> Items { get; private set; }
public List<OrderComment> Comments { get; private set; }
public void AddItem(OrderItem item) { /**add item**/ }
public void AddComment(OrderComment comment) { /**add comment**/ }
public override bool Validate() { /**validate**/ }
public void Cancel() { /**cancel**/ }
}
Let's say I have a process that updates a property on the Order entity, for example it changes the CustomerId associated with the order.
I have an IOrderRepository in my domain layer, which would have an implementation (in an outer layer) with a function like this:
Order GetOrder(int orderId)
{
//get entity framework order, items, etc.
//map to domain-layer order and return domain-layer order
}
void UpdateOrder(Order order)
{
//get ENTITY FRAMEWORK order, order items, order comments, etc.
//take DOMAIN order (passed in to this function), and update EF items fetched above
//use a single EF unit of work to commit these changes
}
There's something wrong with my approach. The UpdateOrder function seems heavy for a small change; but it also seems I have to do that if my repository isn't aware of which items on the persistence-ignorant domain model have changed. Should I be handling every type of update in a separate repository function? UpdateMarketplace(int marketplaceId), UpdateCustomer(int customerId)?
As I'm typing this, I'm also wondering...maybe the way I have it above is not too heavy? If I change one property, even though I'm doing all of the above, perhaps Entity Framework will recognize that the values being assigned are the same and will only send the one db column update to SQL?
How can I take my Order domain model (fetching is straightforward enough), perform some operation or operations on it that may be limited in scope, and then persist the model using Entity Framework?
You need to look into the Unit of Work pattern. Your UoW keeps track of the changes, so when you get your order from your repository and modify it, you call UnitOfWork.SaveChanges() which should persist all the changes.
Using Entity Framework, your DbContext is basically the Unit of Work but I would create a simpler interface around it so you can abstract it away for easier usage in your higher layers.
Regarding EF, I would recommend mapping your domain entities directly using the code first approach. I would also turn off lazy loading and all the magic stuff so you have full control and less "surprises".
Unfortunately I'm not allowed to share our code but we have all this working pretty effectively with the new EF6 Alpha 3. I would recommend you taking a look at Microsoft Spain's nlayerapp for some implementation examples. I don't agree with many of their design decisions (also, see this review), but I think you can draw some inspiration from the Entity Framework parts. Take a look at their Unit of Work implementation and especially how they have abstracted it away for easier usage in the higher layers, and how they use it in their application services.
I will also recommend looking into creating a generic repository to avoid duplicating lots of logic in your aggregate specific repositories. MS Spain has one here, but you should also take a look at this thread.
Please have a look at this SO question where I gave an example of how I've implemented UoW & Repositories.
As #Tommy Jakobsen told you, your domain entities should be your EF entities, it would avoid you to add a useless mapping layer.
Hope that helps!
You may check ASP.NET Boilerplate's Unit Of Work implementation: http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work
It's open source project, you can check codes. Also, you can directly use it.

ViewModel Redundancy Clarification

I was recently reading about ViewModel and its advantages. I am able to understand why it is needed, however the question I have is If i have two classes for the same object(ie. Person class), doesn't i make the code redundant ? Also does it no make future changes a little difficult since you need to make sure the base class model and view model has the same number of properties is that right ? For instance let's say I have table called Person which has
ID
Name
Color
I am creating a hbm for creating the mapping for NHibernate. I have the following model class
public class Person {
public int ID {get;set;}
public string Name {get;set;}
public string color {get;set;} }
If i am correct, the view model class should look like
public class PersonViewModel {
[DisplayName("Full Name")]
public string Name {get;set;}
[DisplayName("Favourite Color")]
public string color {get;set;}
}
First, I have two classess referring to the same object in the db. Even though one class is used for DB purposes and other one is used for View purposes, we still have two class with exactly the same meta data. Secondly, If I introduce a new field in the db, I would need to add it in three places, Base Model class, View Model Class and the HBM file.
Please correct me if I am wrong, how can this be termed as code optimization or a best practice.
It depends on the approach you wish to take, you could expose the model directly as a property of your view model to avoid violating the DRY principle. However, this would violate the Law of Demeter so you would have to balance this, as your views would now be more tightly coupled with your domain model.
Also, in terms of validation, if you expose the model directly then you need to be careful that any property exposed could be set by an end user, even if you don't use the property directly in your view. You are also more likely to have different validation requirements per view, in which case validation would be the concern of the view model.
That's why the general best practice is not to expose your domain models directly to the view. You can use frameworks such as AutoMapper to reduce the data transfer plumbing code between the layers.

How to expose only properties that needed with Web API?

I'm new to ASP.NET Web API.
I saw examples of how you can get and return POCOs in RESTful web application.
I wonder how in real world application you can pass only some of the properties of your POCO (for security and/or message size reasons).
I found that I can use the '[ScriptIgnore]' attribute, but I'm looking for a way to customize which properties to pass according to the requesting controller, for example.
Does there is a nice, out of the box way, to do so?
Thanks
Probably the easiest is to decorate your POCO with System.Runtime.Serialization.DataContractAttribute and the members you want to include with System.Runtime.Serialization.DataMemberAttribute i.e.
[DataContract]
public class MyType
{
[DataMember]
public string Property1 {get; set;}
public string Property2 {get; set;}
public string Property3 {get; set;}
}
In this case only Property1 will be serialized. It;s worth noting, that both XmlMediaTypeFormatter and JsonMediaTypeFormatter will respect DataContract so you don't need any XML/JSON specific attrbiutes.
Now, this will work in simpler solutions, for a real, well rounded approach you'd probably need to resort to DTOs instead of exposing your Models to the client.
You could use Automapper for that, and project Models to DTOs - you have a good introductory article here http://www.mono-software.com/blog/post/Mono/120/Using-AutoMapper-to-handle-DTOs/. Also, with Automapper you can have different types of DTOs created from the same base Model, which, I understand, is something you are interested in.
If you are trying to return multiple manifestations of the same model from different controller it is a harmful design (according to me). If you still want to do it you can make the unwanted properties to 'null' and return the model.
To handle the null objects to ignore from serializing you have to do this somewhere while configuring your formatters (right in global.asax):
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;

Why does my database still create a table when DbSet<EntitySet> is commented out?

No issues really, this is more for my personal comprehension. Using MVC3 + EF 4.1 Code First. I'm trying to make a one-to-one relationship between a Provision and an Enactment.
I tried using the conventional way of making DbSet<Provision> and a DbSet<Enactment>. However, it turned out EF didn't like that. I had to change the OnModelCreation override to define the principal/dependent relationship (fyi Provision is principal, Enactment dependent). I had a bunch of errors and exceptions for some reason. So I tried something a tad creative:
I commented out the public DbSet<Enactment> Enactments { get; set; } line from my Context. Nonetheless, my Provision class still calls for a public virtual Enactment Enactment { get; set; } property. I thought that would make it so that a Provision will just save in its Enactment property an object of the Enactment class itself (if this sounds odd, I apologize I took up programming only a month ago and still learning). That was acceptable, since I thought I would be able to access the Enactment by looking at Provision.Enactment.<EnactmentProperty>.
What surprised me was that even with DbSet commented, the db still created an Enactments table mapped to my Enactment class properties. So if anything it seemed like I got an even better result than anticipated - but I just don't understand the logic behind my code now. Is commenting the particular DbSet and still getting a table normal in the circumstance? Am I playing with fire and should back away from this method?
Commenting DbSet doesn't matter. EF code first uses some conventions which will check you entities and mapping and infer all classes which should be mapped. So if you have any fluent mapping describing some entity or if any entity you explicitly mention in DbSet or mapping has navigation property to other class (which can be entity = EF is able to infer its primary key) it will be mapped as well.