Tip 26 – How to avoid database queries using Stub Entities

What are Stub Entities?

A stub entity is a partially populated entity that stands in for the real thing.

For example this:

Category c = new Category {ID = 5};

is a stub entity.

It has only the ID populated, which indicates this is a stub for Category 5.

When are Stub Entities Useful?

Stub Entities are useful whenever you don’t really need to know everything about an entity, primarily because by using them you can avoid superfluous queries, but also because they are a lot easier to use than EntityKey.

Here are some examples:

Scenario 1 - Building a relationship using a Stub Entity:

This is probably the most common use of Stub Entities, lets say you want to build a relationship between a new product and an existing category, if you know the existing category has ID = 5, by default you would do this:

Product p = new Product {
Name = “Bovril”,
Category = ctx.Categories.First(c => c.ID == 5)
};
ctx.AddToProducts(p);
ctx.SaveChanges();

But this does a database query for the category, which is superfluous if all you are doing is building a relationship. You don’t need the whole entity, you already know all you need (the ID), so you can rewrite this to use a Stub Entity:

Category category = new Category { ID = 5};
//see tips 13 and 16 if you don’t like the string here!
ctx.AttachTo(“Categories”,category);

Product product = new Product {
Name = “Bovril”,
Category = category
};
ctx.AddToProducts(product);
ctx.SaveChanges();

And as a result you save a database query.

Note: You can use this approach to build new relationships via collections too.

Scenario 2 – Delete using a Stub Entity:

The standard way to do a delete looks like this:

Category category = ctx.Categories.First(c => c.ID == 5);
ctx.DeleteObject(category);
ctx.SaveChanges();

The first line is a query, to get an ‘full’ entity, but you can do a delete with a simple stub if the entity has no references to other entities:

Category category = new Category { ID = 5 };
ctx.AttachTo(“Categories”,category);
ctx.DeleteObject(category);
ctx.SaveChanges();

Again using a stub saves a query.

Scenario 3 – Delete a Stub Entity with References

If however the entity you want to delete has a reference (i.e. a product has a Category) the Entity Framework needs to know* about the reference in order to delete. Now if you do a query to get the entity you want to delete the EF gets this extra information automatically using a feature called relationship span.

But again we want to save the query, by using a stub entity we can tell the EF about the relationship using, you guessed it, another stub entity:

Product product = new Product {
ID = 5,
Category = new Category { ID = 5 }
};
ctx.AttachTo(“Products”,product);
ctx.DeleteObject(product);
ctx.SaveChanges();

And here by using two stub entities, we’ve again saved a query

* In .NET 4.0 is you use FK associations, this no longer true. The Entity Framework will happily delete without knowing about the references. As Roger Jennings would say hoorah.

Scenario 4 – Delete a Entity with a Timestamp

If an entity has a column used in concurrency token, generally this is a timestamp, you need to provide that value too, when you create the stub:

Order order = new Order{
OrderNo = 3425,
Timestamp = timestamp,
Customer = new Customer { ID = 7}
};
ctx.AttachTo(“Orders”, order);
ctx.DeleteObject(order);

Used a stub, saved a query.

Scenario 5 – Update an Entity

If you want to update an entity, you just need to attach something that represents the original version of the entity, and again that is where stubs come in:

Person person = new Person{
ID = 65,
Firstname = “Jo”,
Surname = “Andrews”
};
ctx.AttachTo(“People”, person);
person.Surname = “James”; // Yes my wife took my surname!
ctx.SaveChanges();

Used a stub check, saved a query check!

Summary

5 scenarios and 5 saved queries so as you can see Stub Entities are super useful.

Not only do they save database queries, which will make your apps perform and scale better. They also make your code more readable compared to the EntityKey alternatives.

The general pattern for using them is pretty simple too:

  1. Construct a stub Entity with the fields you need.
  2. Attach the stub Entity
  3. Do what you need to (Build Relationship, Delete, Update etc)

Let me know if you have any questions.

This is 26th post in my ongoing series of Entity Framework Tips.