Eliminate Joins by Modifying Entity Framework Models

It makes sense to add associations to Entity Framework if it helps you avoid using Joins.

In a recent article I showed that using Entity Framework navigation properties makes your code considerably simpler than using the more "SQL-like" Joins (though you certainly can do Joins in LINQ). I also suggested that it makes sense to add associations to Entity Framework if it helps you avoid using Joins.

For instance, in the version of the Northwind database I'm using, there's a Region table with RegionId and RegionDescription columns. The Customer table has a corresponding Region column. What the database doesn't have is a foreign key/primary key relationship between the Region and Customer tables. As a result, the default EF model doesn't have navigation properties connecting Regions to Customers or Customers to Regions. If you want Customer information along with the RegionDescription you'll have to use a Join. Fortunately, you can add the association to the model and eliminate Joins.


To create a new association in the EF model, just open the model's edmx file; in the Toolbox, select the Association tool. Then click on one of the entities you want to navigate between (e.g. the Region entity) and drag to the other entity (e.g. the Customer entity). That will add a new navigation property (in this case, called Customers) to the Regions Entity and a new navigation property to the Customers Entity (called Region_1—a name worth changing).

Now switch to the Model Browser (typically nested with Solution Explorer) and, under the Associations node, find your new Association (my example has resulted in an Association called RegionCustomer). In the Properties window, select the Association's Referential Constraint property and click its builder button (the one with the three dots). This will bring up a dialog where you can specify which is the Principal entity in the Assocation (the entity on the "one" side of the relationship—Region, in this case) and what properties are to be used in the relationship (in this case, RegionId from the Region table and Region from the Customer table). That should complete the Association and cause Entity Framework to generate the appropriate Navigation properties.

With the new Association added, you can find all the Customers based on the RegionDescription in the Region entity:

 Dim res = From  r In nw.Regions
Where r.RegionDescription = "Spain"
Select r.Customers

Or, going the other way, retrieve a RegionDescription for a Customer's Region:

 Dim res = From c In  nw.Customers
Where c.CustomerID = "ALFKI"
Select c.Region_1.RegionDescription
If the columns involved contain Nulls you'll probably need to adjust the default settings for the End1 Multiplicity and End2 Multiplicity properties on the Association. If these default to 1…* then your code may blow up when Entity Framework hits the null fields. Changing the multiplicity to 0…* (and setting the column's nullable property to True) will give Entity Framework permission to deal with those null values.

About the Author

Peter Vogel is a principal in PH&V Information Services, specializing in ASP.NET development with expertise in SOA, XML, database, and user interface design. His most recent book ("rtfm*") is on writing effective user manuals, and his blog on technical writing can be found at rtfmphvis.blogspot.com.

Reader Comments:

Sun, Nov 6, 2011 n3cr0fag life insurance 29372 car insurance quotes aztmb

http://www.lifeinsurcover.com/ DOT 29372 http://www.locateinsuronline.com/ DOT aztmb

Fri, Nov 4, 2011 chopsake florida auto insurance 8-)) home insurance nyihrq

http://www.topinsurproviders.com/ DOT 8-)) http://www.insurbenefits.com/ DOT nyihrq

Sun, Oct 30, 2011 Peter Vogel Canada

Tad: I know what you mean about stumbling over it. I'd modified properties on the entity objects and created inheritance hierarchies between them for over a year. One day, I was looking at the model and I thought "I wonder if I can play with the relationships?" Turned out you can--why no one mentions this is a mystery to me. But, I guess, if you have all the relationships you need in the underlying database, it's not critical.

Sat, Oct 29, 2011 Tad

This is one of my favorite features of EF. I kind of tripped over it one time and have been using it ever since. Now they just need to redo how you setup relations to make it as simple as Access. I hate right clicking on a database, selecting properties and then selecting columns through drop downs vs. just drag and drop. They should also fix how the model updates from the database. If I need to change anything ,the model just just update. I shouldn't need to delete, update, add back and update.

Mon, Oct 10, 2011 Peter Vogel Canada

Tomigaspar: Good point! I seriously considered putting that sentence in bold face. Without setting the referential constraint, I bet you get what's called the Cartesian product: The result of joining every row in a table to every other row in the table--and for every table in the SQL query.

Sun, Oct 9, 2011 tomigaspar Slovakia

Be careful not to forget to add the referential constraint to associations. If you wont, it will result in less than wanted SQL commands created by EF for database. Because EF will automaticaly join these tables if queried for parent entity(this happens on associations with 1 and 0..1 multiplicities for sure, I havent tried 0..*). This will go to extremes when including several other tables. because you will end up with X*Y (X- included entities count; Y - associations for parent entity without referential constraint)joins in resulting SQl command, where you would want only X joins. I ended up with more than 40 joins for quite simple query... So be aware of this feature.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above