In my previous post, I showed how to take a simple relationship between Customers and an one Detail per customer build that into a relationship that eagerly loaded the customer record when retrieving a Detail record with CodeFirst in EntityFramework. Now, let’s extend that so that a customer has an Address associated with them. This means, the relationship is as follows:
Detail
Customer
Address
Or, using my favorite Sql Manager Tool http://www.sqlmanager.net/ from EMS Database Management Solutions:
The model is now as follows:
namespace Con1 { public class SiteDB : DbContext { public DbSet<Detail> Details { get; set; } public DbSet<Customer> Customers { get; set; } public DbSet<CustomerAddress> CustomerAddresss { get; set; }<span class="kwrd">public</span> SiteDB(DbConnection connection) : <span class="kwrd">base</span>(connection, <span class="kwrd">true</span>) { <span class="rem">//ctor uses for tracing </span> } <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnModelCreating(DbModelBuilder modelBuilder) { } <span class="kwrd">public</span> SiteDB() { } } <span class="kwrd">public</span> <span class="kwrd">class</span> CustomerAddress { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] <span class="kwrd">public</span> <span class="kwrd">long</span> Id { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> City { get; set; } } <span class="kwrd">public</span> <span class="kwrd">class</span> Customer { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] <span class="kwrd">public</span> <span class="kwrd">long</span> Id { get; set; } [ForeignKey(<span class="str">"CustomerAddressId"</span>)] <span class="kwrd">public</span> CustomerAddress CustomerAddress { get; set; } <span class="kwrd">public</span> <span class="kwrd">long</span> CustomerAddressId { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; } } <span class="kwrd">public</span> <span class="kwrd">class</span> Detail { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] <span class="kwrd">public</span> <span class="kwrd">long</span> Id { get; set; } [ForeignKey(<span class="str">"CustomerId"</span>)] <span class="kwrd">public</span> Customer Customer { get; set; } <span class="kwrd">public</span> <span class="kwrd">long</span> CustomerId { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> DetailDescription { get; set; } }
}
And the code to actually retrieve the data is now as follows (notice the type safe and non type safe include syntax. Both work, but of course I prefer the type safe.
internal class Program { private static void Main(string[] args) { Database.SetInitializer(new SiteDBInitializer());<span class="kwrd">using</span> (var context = <span class="kwrd">new</span> SiteDB()) { Console.WriteLine(context.Customers.Count()); <span class="rem">//var details = context.Details.Include("Customer.CustomerAddress");</span> var details = context.Details.Include(o=>o.Customer.CustomerAddress); <span class="kwrd">foreach</span> (var detail <span class="kwrd">in</span> details) {
Console.WriteLine( String.Format( “DetailId: {0} CustomerId: {1} Customer.Name: {2} Customer.Customeraddress.City: {3}”, detail.Id, detail.CustomerId, detail.Customer.Name, detail.Customer.CustomerAddress.City)); }
} } } <span class="kwrd">internal</span> <span class="kwrd">class</span> SiteDBInitializer : CreateDatabaseIfNotExists<SiteDB> { <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Seed(SiteDB context) { context.Details.Add(<span class="kwrd">new</span> Detail { Customer = <span class="kwrd">new</span> Customer {Name = <span class="str">"pkellner"</span>, CustomerAddress = <span class="kwrd">new</span> CustomerAddress {City = <span class="str">"Hartsdale"</span>}}, DetailDescription = <span class="str">"descr1"</span> }); context.SaveChanges(); } }</pre>
And the result running it is now:
HTH’s.