You’ve probably all heard someone say that Entity Data Model (EDM) and more specifically the Entity Framework (EF) treat associations as first class concepts.
This sentence, seems reasonably benign, but it has a profound effect on the Entity Framework’s behavior.
Allow me to illustrate by way of an example:
Imagine you want to model a Product/Category relationship in the database. A Product belongs to a category, which is usually modeled as a non-nullable FK from Product to Category, and typically looks something like this:
Now if you want to create a new Product that belongs to an existing category, no problem, you just do one insert, which includes the FK value.
This may seem incredibly obvious but it really is the crux of the whole matter. So bear with me.
When viewed in Entity Framework the above data model will look like this:
Notice that there is no CategoryID in the model. Instead we have a strongly typed Category (Navigation) property layered over the Association.
Now if you want to create a new Product in an existing Category in EF you do something like this:
Product p = new Product();
p.Name = “Bovril”;
p.Category = ctx.Categories.FirstOrDefault(
c => c.Name == “Food”
When we call SaveChanges() conceptually the Entity Framework does two inserts here. One to create the new product and one to create an association that relates that new product to the existing category.
Conceptually it is the association insert that sets the CategoryID in the database. In fact there is nothing in the conceptual model (aka EDM, aka CSDL) that indicates that this could be done with just one insert.
Without the mapping information we just don’t know how the Association is modeled.
However once mapping information is available the Entity Framework can and does compensate where appropriate.In this particular example the Entity will recognize that only one insert is required.
This typically means that for the most part you the end user are unaware of the way associations are treated by the Entity Framework.
Like all abstractions however, sometimes it leaks, and those leaks can occasionally cause some problems in end user code.
More on that next time.