Archive for the 'ORM' Category
Entity Framework – Repositories, Fetching Strategies, Specification and Mapping – Using NFetchSpec for Role Driven Development. Parts 1 - 4
Over the course of the next month or so I will be posting a series on using a set of helper libraries which I refer to as NFetchSpec. I have taken the somewhat unusual course of creating this dedicated post that will act as an index of sorts for this series. Another reason for this aggregated index page is that the title of the series accurately reflects the intent of its content however not so much in a search friendly way and I want to make sure that it can be easily found by people who are interested in using Repositories, Fetching Strategies, Specifications and code only mapping.
NFetchSpec aims to provide a basis for using Repositories, Fetching Strategies, Specifications and Code Only mapping using a Role Driven methodology. Here is some example consumer code of NFetchSpec:
Listing 1.0
var customersStartWithA =
new Specification<IMakeCustomerPrefered>
(c => c.CompanyName.StartsWith(”A”));
var fetch = new FetchingStrategy<IMakeCustomerPrefered>(true);
fetch.AddIntentions(new IEagerFetchingIntention[]
{
EagerFetchingIntention.CreateInstance<IMakeCustomerPrefered,
ICollection<IOrder>>(c => c.Orders)
});
var repo = new CustomerBuyingStatusRepository();
var custs =
repo.Get<IMakeCustomerPrefered>(customersStartWithA, fetch);
foreach (var cust in custs)
{
cust.MakePrefered();
}
As described in Part 1.0, a role is an interface that describes a business or system event and can flag our intention; in the case of the code above, the intention is to make the Customer Preferred. Using NFetchSpec, this style of working (using roles) seeps into all aspects of the code. This is certainly not a requirement to use NFetchSpec and I will give some examples to the contrary as we get deeper into the series of posts, but it is the key reason for developing it. In Listing 1.0 we are using NFetchSpec to create a search predicate using a Specification instance, a Fetching Strategy to determine the most appropriate loading for the role and then finally using the Repository to get a Customer to make preferred. The API of NFetchSpec supports writing code like this, where each of the moving parts can be written in line together, however as mentioned in Part 1.0, one of the benefits of working in this role driven way is that we can use some IoC techniques to discover the correct Specifications and Fetching Strategies based on their implementing a given role, i.e, the interface that is specified to the Repositories .Get<TRole>() method. This is closer to the intended proposed usage:
Listing 2.0
var repo = new CustomerBuyingStatusRepository(); var custs = repo.Get<IMakeCustomerPrefered>();
The Code here in Listing 2.0 will instruct the NFetchSpec infrastructure to find a fetching strategy and Specification for this role when the overloaded version of the .Get<TRole>() method is called. This approach makes for an extremely flexible approach, swapping out the most appropriate component – if I don’t like the fetching strategy for a given role, I can simply replace it, facilitating just in time performance tuning (in the case of fetching) as we observe the system over time.
Here are the links to the posts in the series. You might notice that some of the links are not complete meaning that that post is yet to come. I will update this list as new posts make there way out.
Helping the Entity Framework Play it’s <Role> Part 1.0 (posted)
Helping the Entity Framework Play it’s <Role> Part 2.0 (posted)
Helping the Entity Framework Play it’s <Role> Part 3.0 (posted)
Helping the Entity Framework Play it’s <Role> Part 4.0 (posted)
All the code will be available on conclusion with the final post. Just one small thing before signing off, I really want to re-emphasise that it’s a really good idea to watch Udi present the ideas that lead me to attempt accommodating this approach for Entity Framework.
2 commentsHelping Entity Framework v4.0 play it’s <ROLE> – Part 1.0
With the Entity Framework version 4.0 just around the corner, I decided it was again time to address how to make the next version work in an explicit role based manner that also satisfies my wish to work with Domain Driven Design. This is the first of four posts that will detail a set of libraries that I currently have on my workbench, their aim is to aid working with the Entity Framework in the manner I shall describe here and throughout this series of posts. I hesitate to call it a Framework quite yet but it may well reach that point by the time of Entity Framework 4.0 RTM. In the meantime, I refer collectively to this set of libraries as NFetchSpec.
Programming to interfaces is not exactly a new idea right. We should all be familiar with the benefits of decoupling from a classes implementation. If this idea is new to you, here are a couple of links, the first is an interview with the venerable Erich Gamma and the other a video interview with WCF Uber Meister Juval Lowy who is also the author of .NET Components.
A couple years back I enjoyed attending Udi Dahan’s SOA and DDD course, during which I learnt about a lesser known benefit of using interfaces, using them to describe roles within the system. It’s just two weeks now until I have the opportunity to once again enjoy Udi’s SOA and DDD 5 day course and whilst I have been sitting on the code from this series of posts for some time now, it felt like now was a good opportunity to talk more about it. Before continuing with this post I strongly suggest you watch this video presentation Udi gave at QCon London in 2008, this will help provide a solid framing of the background that led up to my attempts to massage the Entity Framework into working in this fashion and ultimately making this series of posts.
As I sat in that classroom back in 2008 it was this simple line of code that really captured my attention, it was something of an aha moment.
Listing 1.0
1: using (ISession s = ORM.OpenSession())
2: using (ITransaction tx = s.BeginTransaction())
3: {
4: IMakeCustomerPreferred c = s.Get<IMakeCustomerPreferred>(id);
5: c.MakePreferred();
6: tx.Commit();
7: }
The line of code to note here is on line 4:, by being explicit and letting the infrastructure code (NHibernate in this case) know what our intention is by specify a role (the IMakeCustomerPreferred interface), we can do some interesting things! We can:
- Make use IoC and service locate the appropriate Fetching Strategy, that is one designed to best suit the role of making a customer preferred. In this example, we want to eagerly fetch all the orders and order lines to make the appropriate adjustments.
- Return an appropriately mapped concrete implementation for the role of IMakeCustomerPreferred. Entity Framework 4.0 code only mapping has made this a possibility.
By being very explicit with the role I can let NFetchSpec do the lifting in finding the most appropriate entities and fetching strategy to load. For performance reasons alone I may have more than one combination. Bear in mind the code in listing 1.0 is part of a service layer and the concrete entity implementing IMakeCustomerPreferred contains a business operation to make a customer preferred – which may involve discounting current orders on hand for example. The equivalent of this block of code for the Entity Framework could indeed abstract away all the following code:
static void Main(string[] args) { var builder = new ContextBuilder<ObjectContext>(); builder.Configurations.Add(new CustomerMapping()); builder.Configurations.Add(new OrderMapping()); builder.RegisterSet<Customer>(“Customers”); builder.RegisterSet<Order>(“Orders”); var cnxString = “Server=BOOMER\\BOOM09;Database=CodeOnly;”+ “Trusted_Connection=True;MultipleActiveResultSets=true”; var connection = new SqlConnection(cnxString); var context = builder.Create(connection); var custs = context.CreateObjectSet<Customer>(); context.Connection.Close(); context.ContextOptions.LazyLoadingEnabled = true; foreach (var cust in custs) { Console.WriteLine(cust.FirstName + ” has {0} orders”, cust.Orders.Count()); } Console.ReadLine(); }
Some of the accompanying Mapping Code
public class CustomerMapping : EntityConfiguration<Customer> { public CustomerMapping() { Property(c => c.CustomerId).IsIdentity(); Property(c => c.FirstName).HasMaxLength(50).IsRequired(); Property(c => c.LastName).HasMaxLength(50).IsRequired(); Relationship(c => c.Orders).IsOptional(); Relationship(c => c.Orders).FromProperty(o => o.Customer); } } public class OrderMapping : EntityConfiguration<Order> { public OrderMapping() { Property(o => o.OrderId).IsIdentity(); Relationship(o => o.Customer).IsRequired(); Relationship(o => o.Customer).IsRequired().FromProperty(c => c.Orders); } }
Before we delve into NFetchSpec deeply in the following posts, let’s take a quick look at some typical consumer code:
Notice also that there is no orthogonal technology bleed in this code, my ORM technology knows nothing of my business entities and my business entities know nothing of my ORM technology. The CustomerBuyingStatusRepository class is a specialised IRepository and through IoC we get the right ObjectContext, the correct mapping, the type of Customer entity that we make preferred and with the correct eager loading to bring across the orders and order lines in one go.
If you want to gain a better understanding of working in this style then I really do urge you to go and watch this video and then return here to continue and follow this series of posts.
If your not sure about Fetching strategies you can get up to speed by reading these links. They will also be useful in preparing the ground for this series of post which relates only to Entity Framework 4.0:
- Fetching Strategies in Entity Framework 4.0 (an early look)
- 11 part series on Repositories, Fetching Strategies and Specifications (EF 1.0)
- A slimmed down Fetching Strategy for out of the box Entity Framework code.
This series of posts (probably 4 in total) will cover the same aspects that were covered in the 11 part series on Repositories, Fetching Strategies and Specifications, however we will look at how the story around most of those elements in NFetchSpec have been improved by virtue of some of the new excellent features in Entity Framework 4.0, such as POCO Entity support and Code Only Mapping which will not feature entirely in 4.0 but sometime (hopefully) shortly after. In part 2.0 we will begin to deep dive into NFetchSpec and I will make the code available for download.
8 commentsAddressing the pain of Entity Frameworks ObjectQuery<T>.Include()
Well to be fair it’s not all the fault of .Include() alone, for me there is a real friction in the whole loading story in Entity Framework version 1 & 4 and it’s the direct result of the ‘fetching’ aspect of the API being fractured. For eager fetching we have:
ObjectQuery<T>.Include("Name.Your.Poison");
which goes for both version 1.0 and 4.0. Many people take issue with this due to the magic string alone.
For lazy loading we have two different mechanisms depending on which version of Entity Framework we are dealing with. Firstly in version 1.0 there is the unsightly :
ctx.Customers.First().Orders.IsLoaded; ctx.Customers.First().Orders.Load();
and for version 4.0 we have the greatly appreciated improvement of :
ObjectContext.ContextOptions.LazyLoadingEnabled = true
Has Enough Changed?
However, despite this improvement it remains a fact that the two aspects of loading (lazy and eager) are from an API perspective, quite separate. I will cover how I plan to deal with this in Entity Framework 4.0 in a soon to follow series of posts.
Quite a while back I posted several times on how to achieve lazy loading with Entity Framework Version 1.0 with a framework I put together with the aid of PostSharp to weave some of its magic. It included a Repository, Specifications for strongly typed predicates for Query Builder methods and Fetching Strategies that instructed the framework which parts of an entities graph to lazily or eagerly fetch. As I said, the framework did include Fetching strategies however the framing of their design was targeted to that framework specifically and not general run of the mill Entity Framework usage. In the months since I keep coming upon different ways people (including Mattieu / Jamie / Julie) are trying to deal with the ObjectQuery<T>.Include() method, this prompted me to slim down the Fetching Strategy from my previous version and revisit it here for a more generalised usage in Entity Framework 1.0. Given the following entity model:
Using this model based on the venerable Northwind database, our usage might be something like:
static void Main(string[] args) { var ctx = new NorthwindEntities(); var fetch = new FetchingStrategy<Customer>(); var orders = EagerFetchingIntention .CreateInstance<Customer, EntityCollection<Order>>(c => c.Orders); var orderLines = EagerFetchingIntention .CreateInstance<Order, EntityCollection<OrderLine>>(o => o.OrderLines); var combine = orders.And(orderLines); fetch.AddIntentions(new[]{combine}); var custsWithOrdersAndLines = from c in ctx.Customers .WithFetchingStratey(fetch) select c; foreach (var cust in custsWithOrdersAndLines) { Console.WriteLine(string.Format(“The customer ID is {0} and they “ + “have {1} orders with {2} order lines!”, cust.CustomerID, cust.Orders.Count(), cust.Orders.Sum(o => o.OrderLines.Count))); } }








