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.
Related
Below is the Project code-first class mapped directly to the database through the Entity Framework 6 Fluent API:
public class Project
{
public Project()
{}
public int ProjectId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public ICollection<ProjectVersion> ProjectVersions { get; set; }
}
Anemic models in Domain-Driven Design are an anti-pattern. I want to use this same class in my domain model instead of creating a separate Project domain class and having to perform complicated mapping between the two in the repository (and with the hundreds of other models we have).
This is how Project would look as a domain model class:
public class Project
{
private readonly List<ProjectVersion> projectVersions;
public Project(string name, string description)
{
Name = name;
Description = description;
projectVersions = new List<ProjectVersion>();
}
public int ProjectId { get; private set; }
public string Name { get; set; }
public bool IsActive { get; private set; }
public IEnumerable<ProjectVersion> ProjectVersions
{
get
{
return projectVersions;
}
}
public void AddVersion(ProjectVersion version)
{
projectVersions.Add(version);
}
}
From what I have read, I am able to map to a private fields with EF's Fluent API.
Are there any any shortcomings here? Am I taking an unnecessary shortcut?
The only problem I can forsee is when a business domain model would essentially consist of data from two or more data entities.
I think you're making a mistake in this approach. I think you should separate the concerns of your Domain models from the concerns of your Entity models. Uncle Bob wrote a strange, but on-point blog post about this here: Dance You Imps! (seriously, it's a weird post.) The ORM's job is to act as a contract to your database. Your domain models' job is to provide the functionality. In short, you should let Entity Framework function the way it wants to. If you want to do DDD, write a mapping layer to convert EF models to your Domain models.
Are there any any shortcomings here?
Possibly.
It is true that EF can address private members, so it is able to materialize a Project with a loaded ProjectVersions collection if you want. It won't use the AddVersion method for that (it doesn't even know it exists), but it will add objects to the projectVersions member.
In the application code you want to add versions through a method. There may be some problems with this AddVersion method though.
You can always add a ProjectVersion, but you will never be sure whether it will be stored, because for EF to track the addition projectVersions must have been loaded. However, you don't want a domain entity to be responsible for loading its own children from the database. So AddVersion gives the class a responsibility it can't fulfil to the full.
Calling AddVersion can occur any moment during the lifespan if the object. Usually this will be longer than the lifespan of the context by which it was created and tracked. So you can't rely on lazy loading to come to the rescue if the collection is not loaded yet. (ProjectVersions should virtual ICollection for that, by the way).
The conclusion is that you always have to load projectVersions eagerly (through Include) for AddVersion to be guaranteed to work properly. So there is a dependency in your application between two not obviously related pieces of code, which is a potential source of bugs.
When it is time to save the Project, you have to attach it to a context and find out which ProjectVersion should be marked for insert and which for update (and there's not even a RemoveVersion method yet.
All in all, it is much simpler to add versions in a service method that does all required actions within the lifecycle of a context. An added version will be marked for insert automatically. Likewise, any updated and deleted version will be marked correctly.
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.
I've got an ADO.NET background and its the first time I've used Entity Framework in a serious project so I've gone ahead and got VS2012 and am using .NET 4.5 and entity framework 5.
I'm taking the data first approach and have created the database, generated the .edmx and also seperated out the POCOS from the context using this method: http://allen-conway-dotnet.blogspot.co.uk/2013/01/separating-entity-framework-poco.html
So my solution looks like this:
Data.Access (where I access the EF context and return POCOS to Business Layer)
Data.Model (where the POCOs are)
Data.Repository (where the context sites)
Presentation.Admin.Website
Now say I have the following table in the database / POCO class (just an example - not real)
namespace Data.Model
{
using System;
using System.Collections.Generic;
public partial class Car
{
public Car()
{
this.Parts= new HashSet<Parts>();
}
public int ID { get; set; }
public string Manufacturer { get; set; }
public string Model{ get; set; }
public Nullable<bool> Enabled { get; set; }
public virtual ICollection<Parts> Parts{ get; set; }
}
}
Now say all the cars in the database have an web service or even just a link to a URL which returns XML and gives me a list of available parts. The way in which each car retrieves the parts data is different (some are REST, some WCF, some from a CSV file, etc).
So I want to define classes that extend Car and define a "GetParts()" method which will have specific business logic to get parts for that particular car.
I also want to be able to get all cars from the database and loop them, calling the GetParts method for each one to retrieve the data.
I am thinking I need to define an interface or abstract class ICar declaring the GetParts method and somehow incorporating the Car POCO but getting confused about how to go about coding this.
Can anyone explain briefly how I can structure my code to get this done, perhaps suggesting a design pattern?
I'm taking the data first approach
The way in which each car retrieves the parts data is different (some
are REST, some WCF, some from a CSV file, etc).
Considering your type of data store is variable and you presumably want a reusable model then I think the choice of using EF database first is not a good one for you. Better to go with code first.
So I want to define classes that extend Car and define a "GetParts()"
method which will have specific business logic to get parts for that
particular car.
Your model should be persistence ignorant. I would not consider extending or hardcoding a data store specific GetParts() if that's what you are after.
perhaps suggesting a design pattern?
Perhaps look into using a repository to provide a layer of abstraction over your data mapping.
I'm still getting accustomed to EF Code First, having spent years working with the Ruby ORM, ActiveRecord. ActiveRecord used to have all sorts of callbacks like before_validation and before_save, where it was possible to modify the object before it would be sent off to the data layer. I am wondering if there is an equivalent technique in EF Code First object modeling.
I know how to set object members at the time of instantiation, of course, (to set default values and so forth) but sometimes you need to intervene at different moments in the object lifecycle.
To use a slightly contrived example, say I have a join table linking Authors and Plays, represented with a corresponding Authoring object:
public class Authoring
{
public int ID { get; set; }
[Required]
public int Position { get; set; }
[Required]
public virtual Play Play { get; set; }
[Required]
public virtual Author Author { get; set; }
}
where Position represents a zero-indexed ordering of the Authors associated to a given Play. (You might have a single "South Pacific" Play with two authors: a "Rodgers" author with a Position 0 and a "Hammerstein" author with a Position 1.)
Let's say I wanted to create a method that, before saving away an Authoring record, it checked to see if there were any existing authors for the Play to which it was associated. If no, it set the Position to 0. If yes, it would find set the Position of the highest value associated with that Play and increment by one.
Where would I implement such logic within an EF code first model layer? And, in other cases, what if I wanted to massage data in code before it is checked for validation errors?
Basically, I'm looking for an equivalent to the Rails lifecycle hooks mentioned above, or some way to fake it at least. :)
You can override DbContext.SaveChanges, do the fix up there and call into base.SaveChanges(). If you do that you may want to call DetectChanges before doing the fix up. Btw. the very same issue is discussed in Programming Entity Framework DbContext book (ISBN 978-1-449-31296-1) on pages 192-194. And yes, this is in context of validation...
You can implement IValidatableObject. That gives you a single hook:
IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
And you can apply your validation logic there.
There's also a SavingChanges event on ObjectContext (which you can obtain from the DbContext).
You could just create a custom IDoStuffOnSave interface and apply it to your entities that need to execute some logic on save (there's nothing out of the box)
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.