Entity Framework 4 – Entity Dependency Injection


When dealing with a fat domain model, there is often a need to be able to inject different services into your entities.
e.g. you might want to inject some domain service like “ITaxCalcualtorService” or an infrastructure service like “IEmailNotificationService” into your entities.

If we rely completely on eager loading, then this is not a big problem, we can simply let or repositories iterate over each entity once we have fetched them from the DB and inject our services.
But when it comes to Lazy Load, we can no longer do this, in this case we need to get notified by the O/R mapper when an entity have been materialized so that we can inject our services into it.

If you are aiming to use Entity Framework 4 once it is released, you can accomplish this with the following code snippet:


..inside your own EF container class..

public MyContext()
    : base("name=MyContext", "MyModelContainer")
{
    ...
    ObjectStateManager.ObjectStateManagerChanged +=
    ObjectStateManagerChanged;
}

// this handler gets called each time the
// containers statemanager is changed
void ObjectStateManagerChanged(object sender,
                          CollectionChangeEventArgs e)
{
    // we are only interested in entities that
    // have been added to the state manager
    if (e.Action != CollectionChangeAction.Add)
        return;

    var state = ObjectStateManager
                    .GetObjectStateEntry(e.Element).State;

    // we are only interested in entities that
    // are unchanged (that is; loaded from DB)
if (state != System.Data.EntityState.Unchanged)
        return;

    OnEntityMaterialized(e.Element);
}

// this method gets called each time
// an entity have been materialized
private void OnEntityMaterialized(object entity)
{
    if (entity is Order)
    {
        Order order = entity as Order;
        // use property injection to assign 
        // a taxcalculator service to the order
        order.TaxCalculatorService =
SomeDIContainer.GetObject<ITaxCalculatorService>();
    }
}

The above is a very naïve example, but it does show how you can catch the materialization of a specific entity type and then configure that entity.

This allows us to add complex domain logic to our entities.
We can for example call a method like: “order.CalculateTotals()” where the CalculateTotals method now uses the ITaxCalculatorService.

HTH.

//Roger

Entity Framework 4 – “Almost” POCO


This is a short rant..

I have been very impressed with EF4 so far, but I’ve now found out that EF4 will NOT support enums.
I find this is very strange, I can’t see how Microsoft can claim POCO support and not support one of the most common code constructs.

More info here:

http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/7659feab-d348-4367-b2cd-0456b20262fe

Someone might claim that you can create a private property containing the mapped integer value and then make a public property exposing the enum.
But this comes with two major drawbacks:

1) You can’t create Linq queries that are executed at DB level if you use unmapped properties.
The Linq query would have to use the integer property, and thus loosing it’s semantics.

2) That is not POCO, that is mapper requirements leaking all over the place.

Entity Framework 4 – Using Eager Loading


When Linq To Sql was released we were told that it did support eager loading.
Which was a bit misleading, it did allow us to fetch the data we wanted upfront, but it did so by issuing one database query per object in the result set.
That is, one query per collection per object, which is a complete performance nightmare. (Ripple loading)

Now in Entity Framework 4, we can actually do true eager loading.
EF4 will issue a single query that fetches the data for all the objects in a graph.
This have been possible in other mappers for a long time, but I still think it is awesome that Microsoft have finally listened to the community and created a framework that from what I’ve seen so far, does exactly what we want.

So how do you use eager loading in EF4 ?

Eager loading is activated by calling “ObjectSet[of T].Include(“Details.Product”)”, that is, a dot separated property path.
You can also call include multiple times if you want to load different paths in the same query.

There are also a few attempts out in the blog world to try to make it easier to deal with eager loading, e.g. by trying to remove the untyped string and use lambda expressions instead.

I personally don’t like the lambda approach since you can’t traverse a collection property that way; “Orders.Details.Product” , there is no way to write that as a short and simple lambda.

My own take on this is to use extension methods instead.
I always use eager loading on my aggregates, so I want a simple way to tell my EF context to add the load spans for my aggregates when I issue a query.
(Aggregates are about consistency, and Lazy Load causes consistency issues within the aggregate, so I try to avoid that)

Here is how I create my exstension methods for loading complete aggregates:

public static class ContextExtensions
{
  public static ObjectQuery<Order> 
           AsOrderAggregate(this ObjectSet<Order> self)
  {
    return self
        .Include("Details.ProductSnapshot")
        .Include("CustomerSnapshot");
  }
}

This makes it possible to use the load spans directly on my context without adding anything special to the context itself.
(You can of course add this very same method inside your context if you want, I simply like small interfaces that I can extend from the outside)

This way, you can now issue a query using load spans like this:

var orders = from order in context.OrderSet.AsOrderAggregate()
             select order;

And if you want to make a projection query you can simply drop the “AsOrderAggregate” and fetch what you want.

HTH.

//Roger

Entity Framework 4 – Managing inverse properties


[EDIT]
I was wrong!

It is perfectly possible to do one directional associations in EF4 and POCO mode.
You simply have to manually remove the “ <NavigationProperty ..” tags from your mapping files.

Awesome work EF4 design team :-)

[/EDIT]

Original post:
To my surprise I’ve found out that Entity Framework 4 don’t support one directional collection properties.
That is, if you have the entity “Order” which has an “Details” property, then the “OrderDetail” entity _must_ have an “Order” property.

To make things worse, those properties do not have any auto sync mechanism if you are using POCO entities.
They could very well have supported this by adding an inverse management aspect to their run-time proxies that they use for lazy loading in POCO.

While I do think this is a lacking feature, it is not really a show stopper for me.
We can work around this problem by applying the “Law of Demeter” principle.

We can design our entities like this:

OrderDetail:

public class OrderDetail
{
    ...properties...

    [Obsolete("For EF4 Only!",true)]
    public OrderDetail()
    { }

    public OrderDetail(Order order)
    {
        this.Order = order;
    }
}

Order:

public class Order
{
    ...properties...

    public void AddProduct(Product product,
                                   double quantity,
                                   double itemPrice)
    {
        var detail = new OrderDetail(this)
        {

//offtopic: you might want to associate
//the product via ID or via a snapshot instead
//depending on how you deal with cross aggregate references
            Product = product,

            Quantity = quantity,
            ItemPrice = itemPrice,
        };

        Details.Add(detail);
    }
}

This way, we get a whole bunch of positive effects:

We solve the problem with inverse properties, inverse management is handled inside the “AddProduct” method in the order.

We get a nice way to handle consistency in our aggregate roots, the methods can easily update any accumulated values in the order or change status of the order when we add or remove order details.
This is what aggregates in DDD is all about so you should probably do this anyway, regardless if EF4 did support inverse property management or not.

We add domain semantics to the model, “AddProduct” or “ChangeQuantity” have meaning in our model, thus we get a more self explaining model.

This is a quite nice example of how lacking framework features can force you to write better code.
If we did have support for inverse property management, we might get sloppy and just go the path of least resistance.

//Roger

Entity Framework 4 – Where Entity.Id in Array


Here is a little trick if you want to issue a query to the database and select a batch of entities by ID only:

//assemble an array of ID values
int[] customerIds= new int[] { 1, 2, 3 };

var customers = from customer in context.CustomerSet
                where customerIds.Contains(customer.Id)
                select customer;

This will make Entity Framework issue an SQL query with the where clause “where customerId in (1,2,3)”, and thus, you can batch select specific entities with a single query.
I will get back to this idea in a later post because this is related to how I design my entities and aggregates in DDD.

//Rogerr