Self-referencing relationship in Entity Framework
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");
modelBuild开发者_如何学Goer.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?
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.
精彩评论