EF 4 – Implementing Lazy Loading For My POCO
In my last post, I provided a simple end-to-end example where I used the Entity Framework designer to generate an Entity Data Model (EDM), I turned off the default code generation and implemented my own POCOs. Everything worked fine, but at the end of the post I pointed out that I no longer had the Lazy Loading capability I had with the designer generated objects.
Get the Sample Code
You can download the sample code here.
Lazy Loading for POCOs
At this point, I have a few POCOs which, by their nature, are very simple classes, as well as my context object. See the Customer class below:
public class Customer { public string CustomerID { get; set; } public string CompanyName { get; set; } List<Order> orders = new List<Order>(); public List<Order> Orders { get { return orders; } set { orders = value; } } }
The behavior that I am looking for is: if the Orders for a Customer are accessed and they haven’t been loaded (don’t exist in the context) yet, a call is automatically made to load the Orders for that Customer. Were you implementing this lazy loading functionality yourself, you might imagine adding some code to the getter for Orders. This code would check to see if the Orders were loaded and, if not, make a call to load them.
That would certainly work, but your class would no longer be a POCO, would it? You would have likely imposed some sort of dependency on the framework or at least implemented some data access logic. What you really want is the framework to provide the lazy loading feature set, while maintaining *no* dependencies on any framework from your POCOs.
Lazy Loading Via Dynamically Generated Proxy
So, we have reached a bit of an impasse. We want to call our lazy loading logic from our getter in our POCO, but by doing that, we would have bound it to the framework and have turned our POCO into a DOOF (Dependant On Other Framework – yeah, I just made that up). This is where dynamically generated proxies come in. If you opt in, the framework will dynamically generate a type that derives from your POCO type. This derived type can override certain properties and “inject” new functionality like lazy loading.
In POCO Proxies Part 1 on the ADO.NET Team Blog, they illustrated a simple example of how lazy loading functionality could be injected. Below is a screenshot from that example. Notice that the Orders property is overridden and that a call to the lazy loading functionality (DoLazyLoading() in this simple example) was injected.
Implementing Lazy Loading for your POCOs
Most of the steps required for implementing lazy loading for your POCO via dynamically generated proxy should be pretty straight forward from the above. However for clarity sake, I want to be pretty explicit on what you need to do to enable this behavior:
- Ensure proxy creation is on. The context.ContextOptions.ProxyCreationEnabled property must be true. It is true by default.
- Lazy loading must be enabled. The context.ContextOptions.LazyLoadingEnabled property myst be true. You can set this in the default constructor of your context object. Notice the constructor in my context object below. I set LazyLoadingEnabled to true, as well as explicitly turned on ProxyCreationEnabled explicitly.
public NorthwindContext() : base("name=NorthwindContext") { this.ContextOptions.ProxyCreationEnabled = true; this.ContextOptions.LazyLoadingEnabled = true; }
- You have to be able to implement your POCO in a dynamically generated assembly. Make sure your class is not sealed and is marked public.
- Declare any navigation properties that you want to implement lazy loading with as virtual. See the code below for my customer object. I have marked the Orders navigation property as virtual.
namespace NorthwindModel { public class Customer { public string CustomerID { get; set; } public string CompanyName { get; set; } List<Order> orders = new List<Order>(); public virtual List<Order> Orders { get { return orders; } set { orders = value; } } } }
That is it. You can now run the sample application and you automatically get lazy loading functionality. Let’s have a look. As you can see below, the objects were, in fact, loaded.
Having a look at sql profiler, you can see that 4 queries in all were run. The first was the query to return all of the customers (3). Tthe next 3 were called via lazy loading.
Each time we accessed the Orders from a customer, the lazy loading functionality was called.
(see this post for a discussion of when to use eager vs. lazy loading)
Reference Properties Benefit From Lazy Loading, As Well
Lest you assume that lazy loading is just for collections, it works for reference properties, as well. To illustrate, I have added an Orders ObjectSet to my NorthwindContext:
public class NorthwindContext : ObjectContext { …
public ObjectSet<Order> Orders { get { if (orders == null) { orders = base.CreateObjectSet<Order>(); } return orders; } } private ObjectSet<Order> orders; }
I then changed the code in Program.cs to target my new Orders ObjectSet:
using (NorthwindContext nw = new NorthwindContext()) { var query = from o in nw.Orders where (o.OrderID == 10682 || o.OrderID == 10856 || o.OrderID == 10355) select o; foreach (Order order in query) { Console.WriteLine("ID: {0}", order.OrderID); Console.WriteLine("Date: {0}", order.OrderDate.ToString()); if (order.Customer != null) Console.WriteLine("Customer: {0}", order.Customer.CompanyName); Console.WriteLine(""); } }
Running this code, you will see the following output:
By simply marking the Customer property in my Order POCO as virtual, I will get lazy loading:
namespace NorthwindModel { public class Order { public int OrderID { get; set; } public string CustomerID { get; set; } public DateTime OrderDate { get; set; } public virtual Customer Customer { get; set; } } }
Taking a look at sql profiler, you will see that additional queries were run to return customer information that was not already loaded in the context. Notice that only 2 queries were run via lazy loading. This is because the customer for order id 10682 is the same as the customer for order id 10856. It only had to be loaded into the context once.
Summary
The Entity Framework provides powerful lazy loading functionality for POCOs, while maintaining their integrity. If you are interested in a more in-depth discussion of this functionality, I would suggest having a look at the following post: http://blogs.msdn.com/adonet/archive/2009/12/22/poco-proxies-part-1.aspx.
EF 4 – Implementing POCO Objects
The EF team has released the POCO template for use with VSTS 2010 Beta 2. I thought I might examine POCO support in the new version of the Entity Framework without taking advantage of the template first, then get into the template in a later post. This post will provide a simple end-to-end sample of implementing POCO objects in EF4 (Beta 2). If you are reading this, you probably already know that POCO refers to “Plain Old CLR Objects”. These are simple objects that are free of any framework dependencies. POCO objects do not have to inherit from specific classes, do not have to implement specific interfaces, nor do they require any specific attributes. They are simple, lightweight objects that are used to pass data around.
The Entity Framework 4 provides support for POCOs. This post will illustrate this using a simple example from Northwind, a database that everyone has access to. Feel free to follow along. All you need is the following:
- Beta 2 version of Visual Studio 2010 and .NET 4 and
- Microsoft ADO.NET Entity Framework Feature Community Technology Preview 2
The SQL Data Model
Above you will see a small part of the SQL Data Model for Northwind. These are the 2 tables that I am going to use. In fact, for simplicity sake, I am not going to return each column from the 2 tables. I have highlighted the columns that I plan on using. With that out of the way, let’s get started:
Implementing this Simple Model without POCO
I will get started implementing this simple model without POCO. Here goes:
- Open Visual Studio 2010 Beta 2
- Create a new Console Application
- Click File > New > Project
- Choose Console Application – For me it is under: C# > Windows
- Give It any name you want. I’ll name mine SimplePOCO
- Add the ADO/.NET Entity Data Model:
- Click Add > New Item > ADO.NET Entity Data Model
- Name It: NorthwindModel
- Click ‘Add’
- Choose ‘Generate From Database’ and click ‘Next’
- Choose a connection to the Northwind database
- Choose the tables and set the Model Namespace
- Choose the Customers and Orders Tables
- Set the Model Namespace to NorthwindModel. This is an important decision. As you might infer, this will act as the namespace for your entire conceptual schema. In other words, if you generate objects to represent your entities, they will have the NorthwindModel CLR namespace. If you choose to create POCO objects, you will have to namespace them with NorthwindModel.
- Click ‘Finish’
- Delete the unneeded properties from our conceptual model. Remember that earlier I highlighted the columns in the database model that I wanted to use. We need to delete the properties from our conceptual model that map to the unneeded columns.
- Simply single click on the unneeded columns (see image below) and click delete
- You can multi-select columns
- Write some code in Program.cs to test the model:
- Open Program.cs
- Type the following code under Static Void Main
static void Main(string[] args) { using (NorthwindContext nw = new NorthwindContext()) { var query = from c in nw.Customers where c.CompanyName.StartsWith("A") select c; foreach (Customer c in query) { Console.WriteLine("{0}", c.CompanyName); foreach (Order order in c.Orders) { Console.WriteLine("\t{0}", order.OrderDate.ToString()); } } Console.ReadLine(); } }
- Run It! You will see that not only does our model work, but we got lazy loading for free (I’ll get into Lazy Loading in another blog post.)
That is it for implementing the model without POCO. To illustrate that the object that were generated by the EF are not POCO, simply open the NorthwindModel.Designer.cs file. This contains all of the designer-generated code.
You need only take a brief look at the Customer or Order class to see that they have both EF attributes, as well as implement classes from the framework:
What Have We Got So Far?
Before I move on to the POCO side of things, I think it is probably best to describe a bit more about what has been done so far. To start with, we used a wizard to generate an Entity Data Model (EDM) from our database schema. If you are not familiar with what an EDM is, it contains a schema to the physical store (database), a schema for our conceptual model (how we want to see the data in our application) and a mapping between the two. If you open the *.edmx file with an XML Editor (Right-Click NorthwindModel.edmx > Open With > XML Editor, you will see that, aside from the designer markup, the edmx is just that.
The second relevant thing that happened was that the designer generated some classes for us that map to the entities defined in the conceptual side of the EDM (using a template against the EDM). You can see these classes if you open up the NorthwindModel.Designer.cs file. These are the classes that will be used if you go through Object Services. If you are not familiar with Object Services, you can think of it this way: if you think of the Entity Framework as an ORM, Object Services provides the O. In other words, if your query (LINQ to Entities or Entity SQL) returns objects, you are going through Object Services. As seen in the step-by-step guide above, the classes are far from POCO. There are multiple dependencies on the Entity Framework in the form of both attributes and inheritance.
Implementing the POCO Objects
In order to implement POCO Object, we first need to turn off the code generation that occurs by default. Next, we create our POCO Objects. Here are the steps:
- Set the Code Generation Strategy to "None"
- Make sure the properties pane is visible
- Click on whitespace in the edmx designer
- In the properties window, set Code Generation Strategy to "None"
- Add the Customer Class to the project
- Right-Click the project > Add > Class
- Name it Customer.cs
- Change the namespace to NorthwindModel (Remember earlier that we set the model namespace to this)
- Implement the Customer class so it looks like the following (excluding using statements)
namespace NorthwindModel { public class Customer { public string CustomerID { get; set; } public string CompanyName { get; set; } List<Order> orders = new List<Order>(); public List<Order> Orders { get { return orders; } set { orders = value; } } } }
- Add the Order Class to the project
- Right-Click the project > Add > Class
- Name it Order.cs
- Change the namespace to NorthwindModel (Remember earlier that we set the model namespace to this)
- Implement the Order class so it looks like the following (excluding using statements)
namespace NorthwindModel { public class Order { public int OrderID { get; set; } public string CustomerID { get; set; } public DateTime OrderDate { get; set; } public Customer Customer { get; set; } } }
- We now need to add the context class. This is a class that inherits from ObjectContext and acts as the gateway or into your objects. You go through this context to access your entities as objects.
- Right-Click the project > Add > Class
- Name it NorthwindContext.cs
- Change the namespace to NorthwindModel
- Implement the NorthwindContext class so it looks like the following
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Objects; namespace NorthwindModel { public class NorthwindContext : ObjectContext { public NorthwindContext() : base("name=NorthwindContext"){} public ObjectSet<Customer> Customers { get { if (customers == null) { customers = base.CreateObjectSet<Customer>(); //"NorthwindContext.Customers"); } return customers; } } private ObjectSet<Customer> customers; } }
- Add a using statement to Program.cs for NorthwindModel:
using NorthwindModel; - Run It!
Summary
In this simple tutorial, we created an Entity Data Model, swapped out the objects that are generated by the designer for some custom POCOs that we created and wrote our own context object to expose our new object layer. At the very end, our example worked, but we did not get some of the services that the designer-generated objects provided. Most obviously, we did not get lazy loading. I will put together a post for Monday that will illustrate how easy it is to implement that. Oh yeah, and I’ll show off the new POCO template next week, as well.
Is Lazy Loading in EF 4 Evil or the Second Coming?
(As you probably know) The Entity Framework provides you with various options for loading related entities. In Entity Framework 4, you will have the choice to implement eager loading, explicit loading and now… lazy loading. Lazy loading was not available in version 1. A quick search on ‘Lazy Loading’ will yield opinions from 2 very different camps. Some folks see lazy loading as a necessity for an ORM, while others believe it to be evil. So, who is right? This post will examine that question. If you are not familiar with all of the load options are, I will start the post with a brief description of each.
The Code Scenario
We will use the following simple scenario to examine the various load options. In this scenario, we have 2 entities that we are surfacing as objects: Customer and Order. Each customer has 0 to many orders. Imagine the following code accessing the customer and it’s orders (in this case in a console application):
using (NorthwindContext nw = new NorthwindContext()) { var query = from c in nw.Customers where c.CompanyName.StartsWith("A") select c; foreach (Customer c in query) { Console.WriteLine("{0}", c.CompanyName); foreach (Order order in c.Orders) { Console.WriteLine("\t{0}", order.OrderDate.ToString()); } } Console.ReadLine(); }
For the sake of this example, assume that we have 3 customers, with a total of 24 orders between them.
Eager Loading
With eager loading, you structure the initial query in such a way that all of the required objects are returned in the initial query. If you are a SQL person, you can think of this as building a join query. In fact, if you are using the SQLClient Provider, that is exactly what eventually gets executed against SQL Server.
How Do I Do Eager Loading?
You implement eager loading in LINQ to Entities with the ‘Include’ method. An include specifies the related objects to include in the query results. So, given the previous example, we would re-structure the original query to look like this:
var query = from c in nw.Customers.Include("Orders") where c.CompanyName.StartsWith("A") select c;
The Result
Taking a look at the screenshot of SQL Profiler, you will note that in order to return the 3 customers and the 24 associated orders, only 1 query was executed. You can also see the join to the Orders table in the SQL statement that was executed.
Discussion
So is eager loading good? Is it bad? It depends upon the scenario. On a positive note, only 1 query had to be executed. This means that we only needed one connection and incurred the overhead of making one network round trip. On the other hand, every order was returned, resulting in a potentially large resultset. and the initial query included a join which is more expensive than a query against a single table,
In a scenario where a high percentage of the related objects are traversed, eager loading would be a great choice. In a scenario where the object graph can be quite large and you sparingly traverse the related objects, it may be a poor choice.
Explicit Loading
With explicit loading, you explicitly request to load the related objects. In essence, you run an original query to return an object or collection of objects. When you want to process the related objects for that object (or an object in the collection), you explicitly request to have the related objects returned.
How Do I Do Explicit Loading?
You implement explicit loading by calling the Load method on an EntityCollection or EntityReference. So, given the previous example, we would re-structure the code to look like this:
using (NorthwindContext nw = new NorthwindContext()) { var query = from c in nw.Customers where c.CompanyName.StartsWith("A") select c; foreach (Customer c in query) { Console.WriteLine("{0}", c.CompanyName); c.Orders.Load(); foreach (Order order in c.Orders) { Console.WriteLine("\t{0}", order.OrderDate.ToString()); } } Console.ReadLine(); }
Notice that I removed the call to Include. Further note that prior to iterating over the Orders collection, I am explicitly calling Load.
The Result
From the profiler screenshot below, you will notice that 4 queries were run in total. The first query returned just the customer information. Then, I explicitly called ‘Load’ prior to enumerating over the orders for each customer. Each call to load made a separate call to the database with all of the associated overhead: a connection, network round trip, etc.
Discussion
As with eager loading, explicit loading can be performant or not depending upon the scenario. Again, given the scenario where a high percentage of the related objects are traversed, eager loading would likely be a better choice. However in the second scenario where the object graph can be quite large and you sparingly traverse the related objects, explicit loading may be a better choice.
Lazy Loading
With lazy loading, related objects are loaded automatically for you when you access them. You can think of it like explicit loading, but the call to Load is called for you automatically when you access the object in question. To be clear, the query is only run if the objects are not already in the ObjectContext.
How Do I Implement Lazy Loading?
If you are using the Entity Framework designer with the default code generation strategy, you are already set up for lazy loading. The default value of LazyLoadingEnabled for a context is false, However, the default code generation template sets the ContextOptions.LazyLoadingEnabled property to true in each of the constructors for the context – see screenshot below. (You can easily implement lazy loading for POCOs, as well. I’ll illustrate how to do that in a post next week.)
Given that lazy loading is set up, you do not need to do anything else (that is the lazy part). You simply access the objects in question. If the objects are not already in the context and you have not eagerly loaded them with an Include and you have not explicitly loaded them with Load, they will be loaded for you automatically. With lazy loading enabled, the code listed under ‘The Code Scenario’ at the top of this post will work as-is.
The Result
The result is the same as the example of explicit loading. In our simple example, 4 queries were run in all.
Discussion
The issue of relative performance is the same as explicit loading.
The History of Lazy Loading and the Entity Framework
As mentioned at the beginning of this post, lazy loading was not available in the first version of the Entity Framework. The mindset was that, with lazy loading, it was possible for someone to unknowingly make network calls. As these calls are expensive, this was viewed as bad. The decision was made to force people to be explicit when making a network call.
This decision was not well received by everyone and not without it’s issues. Take a look at the following excerpt from the now infamous ADO .NET Entity Framework Vote of No Confidence:
The reality was that virtually every ORM on the market supports lazy loading. The excerpt relayed that without this functionality, the developer is required write unnecessary code to get the expected results. Take the code laid out in ‘The Code Scenario’ at the top of this document. Without lazy loading, the results of this code are shown below:
That is not an accurate depiction of the data. To the untrained eye, it appears that each customer has no orders – a bit of a false negative. In v1, the developer would have been required to add the code to see if the orders were loaded and if not, call Load.
Is Lazy Loading Evil or the Second Coming?
It should be mentioned at the outset that the existence of lazy loading (or explicit loading for that matter) does not preclude you from using eager loading in scenarios where that makes sense. Another point to make is that after all is said and done, explicit loading and lazy loading offer the exact same performance benefits and challenges. What this means to me is that if you have implemented explicit loading in the appropriate places, lazy loading is not evil at all. It will behave exactly as though you had made the correct explicit calls.
If you buy into that logic, the remaining issue is with code where eager loading was not implemented appropriately. Antagonists for lazy loading would argue that, in this case, the uninformed developer would be making unnecessary calls to the database without any knowledge (assuming that they never profile their code). Protagonists of lazy loading might mention that a) one should profile one’s code and b) in order to make the code work without lazy loading is to write a bunch of unnecessary code to see if the items were loaded and, if not, load them. They might follow on that if this same uninformed developer failed to write that ancillary code, their solution would be riddled with false negatives.
So, who is right? Both? Neither? It is simply a matter of opinion. There are folks on both sides that will never buy into the contrary viewpoint. Given that both camps are going to theoretically be consumers of the Entity Framework, it should be clear that lazy loading should be an option.
Now, should it be on by default? In beta 2, it is kind of on by default and kind of not. LazyLoadingEnabled is actually defaults to false. However, if you use the default code generation in the EF, it is set to true in all of the constructors for the context object. That is the way it is. The question is: is that ok?
That is actually a tougher question to answer. IMHO, that was a questionable choice. I’m actually ok with having LazyLoadingEnabled defaulting to false. I would have been equally ok with having it default to true. I would probably lean further toward having it default to true, if pushed. However, it has to be one or the other and there are valid reasons for both. At some point you have to make a decision and I assume that is what they did. What I don’t really like is that if you use the default code gen template, it reverses this decision. I think that once you take a stance on the default, you should remain consistent. I understand that it is nice to illustrate how to set this property in the generated code. Perhaps a better decision would have been to (re)set it to false and have a comment pointing out to set it to true.
To conclude, lazy loading is neither evil or the second coming. It is a necessary feature of any ORM today and I’m glad it is in the EF.
Finding a Nursery School
After our first day of house searching with Claire, it was time to look for a nursery school for Jack. We again had a representative from our relocation company to help us with this. For the afternoon, we had meetings set up with 2 schools. Now, right before Claire dropped us off after our house search, she was “kind” enough to give us a map where she had placed little stickers where all of the area nursery schools were. Nice, huh? WRONG. She misplaced and mislabeled at least 2 of the schools as we were soon to find out.
About a half hour after we were dropped off, it began sprinkling mildly. We found our way safely to the first Nursery school. It was situated at the back of a large sports complex. Within the complex was a nice health club and backing up to the complex was a golf club. So, of course, as we were walking towards the nursery school, we were having daydreams of getting in a round before school or getting in a quick workout right after. That was before we entered the nursery school / frat house.
We were right on time for our scheduled appointment and were shown directly in. We were asked to take off our shoes at the door. I remember thinking that that was a good sign because they were concerned about the cleanliness. That thought lasted about 4 nanoseconds – until we walked into the first room. Honestly, there was crap everywhere. Garbage was all over the floors, intermixed with the kids. Creepy toys were everywhere. The place was filthy. All the while, our guide was walking us from room to room telling us about the nursery. I wasn’t listening very hard because it took a lot of effort to not throw up in my mouth.
It is important to be clear that at no time did I ever consider the possibility of leaving my son there. What was weird was that I started feeling intensely guilty for even being there. So it was with massive relief that we left that school and ventured back out into the rain. We were on foot with no car or umbrella, but it was considerably better than the nursery. On another positive note, it wasn’t raining that hard and we did have Claire’s map (start eerie music here).
We decided to head out to our second appointment a bit early so we referred to our trusty map. It looked like about a 15 minute walk, so opted against researching buses, invested in a small umbrella and started our short walk. It turns out our estimate was spot on. We got to the area corresponding to the sticker on Claire’s map in just about 15 minutes. On a slightly less positive note, 2 major issues began to emerge: 1) there was no school in that location and 2) we were now standing in a torrential downpour.
After 15+ years writing software, I have learned a simple lesson. More often than not, when I thought there was a bug in a framework component, it was actually a problem with my code. So when we had a problem with the map, I initially assumed it was really an issue with my interpretation of the map and not the map itself. So, we walked up and down the street where the school should have been eleventy-billion times looking for anything that looked like a school. Nothing.
I should probably mention that we had purchased a pay-as-you-go phone earlier in the day. Being of Scottish descent, I have a frugal streak running through me. Obviously, we bought the cheapest phone available for £10. After 15 minutes looking about in the rain we gave them a call. What you should be picturing right now is an idiot talking into a can connected to a string because that is about as effective as the phone we bought. Between the rain and the traffic, we could hear NOTHING.
At this point, our mini umbrella (again I opted for the cheapest one available) was rendered useless. We were drenched, disheartened and still lost. After another half hour of wandering around, we found an open business and got some directions to the school. It was over a mile up the road. Consulting our trusty map, we noticed that there was a marker for this new location. Unfortunately, it was listed as a different school for which we had an appointment on another day.
You can probably imagine how we looked when we finally made it to the school. We were soaked to the bone. Unfortunately for Carrie, she was wearing brand new jeans that had been washed at most once. The result was that her legs were stained blue. Nice.
The afternoon did end well, though. The school was great. We loved the teachers, the classrooms, basically the whole facility. We had found Jacks new school. Now all we need was a home. More later…
Taking the Housing Trip – Finally
We finally got the Visa thing squared away and were finally able to take our housing trip. The trip was for 4 days in London. In that time, we were supposed to find a home for us to rent, find our temporary housing and identify a school for our son. Again, we had the expertise of our relocation company on which to rely. That is where this part of the story begins…
Finding our House
Carrie had already taken a trip to London a few weeks prior and found a great town just outside of London called Richmond. It is a nice family-oriented spot with shopping, nice restaurants and is on the tube. With that narrowed down, we just needed to find a place to live. So we told our representative, we’ll call her Claire, to look there for us.
I’m at a bit of a loss on how to describe Claire, but I’ll give it a go. Have you ever met someone that thinks they know what’s best for you, regardless of your opinion? Add to that: 2 parts used car salesman and 3 parts rude French waiter. Cover it with gray hair, throw on some lipstick, put it in the oven for 30 minutes and you have Claire.
Now, there is something about me that you may not know. I sold copiers for a year when I was just out of college (I was young; I needed the money). When you take a job hocking boxes they teach you each and every sales tactic.: things like the assumptive close, many little yeses lead to a big yes, etc. Keep that in mind while we describe our encounter with Claire.
Meeting Claire
We were pretty excited when we went to meet Claire. I mean, how many times in your life do you get to find a new home? So it was with that excitement that we sat down with her for the first time. Claire began the conversation letting us know that we were a bit late (we were) and we needed to hurry. This just after she got my wife a coffee.
Next, she let us know that this was the worst time of year to try to rent a house and that most of the good ones were gone. In fact there were 2 houses that were “perfect for us” that just rented out last week. That royally pissed us off because they would have been available to us had our Visas been done on time and we been able to make our original housing trip.
Claire then let us know that she lined up 12 or so houses for us to see. She relayed that she set up the appointments in order of importance. In her opinion, we should probably rent the first house as it was best suited for us. However, in the unlikely event that she was wrong, she had 5 other adequate places for us to see thereafter on day one. The houses on day 2 were pure rubbish (this is because there is nothing available and had nothing to do with her searches btw). With that in mind, Claire was kind enough to let us know that, given all of these factors, it was in our best interest to make an offer by the end of day one. If not, it was likely someone else would make an offer on those properties in short order.
After hearing this, I had some mild, if not severe, flashbacks to copier sales school. Claire had employed every tactic I learned on day 1. She had set expectations, as well as established a high degree of urgency. I wouldn’t have been surprised if she had whipped out a Lanier 6242 (42 copy per minute system I used to sell back in the day), showed me a demo and presented me with a contract. That was how our day started.
Claire’s Top Picks
I do have to say that the first 2 were fine houses she showed us were fine places (we actually rented the 1st, but we’ll get back to that later). The positives were that they both met our requirement of 4 bedrooms (one for us, Jack, an office and guest room) and were close to the tube (the underground train station). They also had a bonus in that they each had a garage and driveway with a parking spot (neither very common in the London area).
The negatives were that both had small reception rooms (we call them family rooms in the US), no fireplaces, small bedrooms and tiny showers. I don’t have the actual square footage, but I would guess around 1000. Now, we knew to expect much smaller houses in the London area. However, these places cost a premium (approximately twice what we could rent our 2800 square foot house in Phoenix for) and for all of that none of our furniture would fit. Forgetting the cost of buying all new furniture, the showers are small enough that I’m not sure I’ll be able to reach up to clean my arm pits – so don’t sit next to me on the train until it can be confirmed.
We gave Claire all of this feedback and we continued the search. We then saw the next 5 or so houses scheduled for that day, but none of them were all that great. We were starting to get concerned because Claire had already warned us that the houses for day 2 stunk, but that was a problem for day 2. It was only noon and we had a half day of looking at nursery schools ahead of us. I’ll detail that tomorrow…


Email Me