1

I am using Entity Framework 4.1 code first and I have two entities and one abstract class that both entities inherits from.

public abstract class Customer
{
    public long CustomerId { get; set; }
    public string Rating { get; set; }
    public int FinancialStatusValue { get; internal set; }
}

public class Organization : Customer
{
    public string Name { get; set; }
    public string Name2 { get; set; }
    public string LegalName { get; set; }
    public string OrganizationNumber { get; set; }
    public string Vat { get; set; }
    public string Duns { get; set; }
    public Organization HeadQuarter { get; set; }
    public virtual ICollection<Organization> ChildOrganizations { get; set; }
}

I map my model with:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Customer>().ToTable("Customer");
        modelBuilder.Entity<Organization>().ToTable("Organization");

        modelBuilder.Entity<Organization>().HasOptional(h => h.HeadQuarter)
            .WithMany(c => c.ChildOrganizations)
            .HasForeignKey(o => o.ParentId);

 }

I then query organization using:

var org = ctx.Customers.OfType<Organization>().Single(c => c.CustomerId == 259033);

ParentId is populated but HeadQuarter and ChildOrganizations are always null.

What am I missing?

RobinHu
  • 374
  • 2
  • 14

1 Answers1

2

You can eager load the navigation properties by using Include:

var org = ctx.Customers.OfType<Organization>()
    .Include(o => o.HeadQuarter)
    .Include(o => o.ChildOrganizations)
    .Single(c => c.CustomerId == 259033);

You can also leverage lazy loading which would load the navigation properties when you access it the first time. You have to declare your navigation properties as virtual. (You did this only for ChildOrganizations but not for HeadQuarter.)

Be aware that Include will only load the navigation properties you exactly specify. It will not load your whole tree structure, i.e. not load Organization.ChildOrganizations.ChildOrganizations, etc.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Thank you for your answer. How does this work if I use ctx.Database.SqlQuery? – RobinHu Oct 10 '11 at 16:29
  • @RobinHu: I have no clue. Ask this better as a separate question ("How to eager load with SqlQuery?" or something). I have a little doubt though that it's possible at all because I believe that the column names which are returned by `SqlQuery` must be the same as the property names of the type `T` - and property names of related entities are not property names on `T`. So, basically `SqlQuery` can only populate scalar properties but not navigation properties. But sure I am not. – Slauma Oct 10 '11 at 16:49