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 system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On with GitHub Copilot App Technical Preview: Turning a Blazor Issue into a PR

    GitHub's brand-new Copilot desktop app, in technical preview, handled a small Blazor issue from planning through pull request creation, but the hands-on test also showed why developers still need to verify agent work in the running app before merging.

  • At Build 2026, Microsoft Sets Up Windows as an OS for AI Agents

    Microsoft's Build 2026 Windows developer announcements point to a broader platform strategy for agentic AI, spanning terminal workflows, local models, app-building skills, Cloud PCs and operating system-level containment.

  • Slammed by Copilot Usage-Based Billing on Day 1, Facing $180 Bill for June

    A journalist using GitHub Copilot Pro details how a broken editorial workflow on day one of usage-based billing led to runaway token consumption, a projected $180 monthly bill, and practical tactics for cutting AI credit burn.

  • AdaBoost.R2 Regression Using C#

    AdaBoost.R2 regression works by building an ensemble of decision trees, training them on reweighted data, and combining their predictions with a weighted median, while also showing how parameter choices affect accuracy and overfitting.

Subscribe on YouTube