2011-10-10 52 views
1

我首先使用實體​​框架4.1代碼,並且我有兩個實體和一個兩個實體都從中繼承的抽象類。實體框架中的自引用關係

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; } 
} 

我映射我的模型:

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); 

} 
使用

我再查詢機構:

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

的ParentId填充,但總部和ChildOrganizations總是空。

我錯過了什麼?

回答

2

你可以貪婪加載使用Include導航性能:

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

您還可以利用延遲加載,當你進入它的第一次這將裝載的導航性能。你必須聲明你的導航屬性爲virtual。 (您只對ChildOrganizations執行此操作,但對於HeadQuarter不支持此操作。)

請注意,Include只會加載您準確指定的導航屬性。它不會加載你的整個樹結構,即不加載Organization.ChildOrganizations.ChildOrganizations等。

+0

謝謝你的回答。如果我使用ctx.Database.SqlQuery ,這是如何工作的? – RobinHu

+0

@RobinHu:我不知道。把這個問題作爲一個單獨的問題提出來(「如何用SqlQuery加載?」或其他)。我有一點疑惑,儘管它有可能,因爲我相信'SqlQuery'返回的列名必須與'T'類屬性名相同 - 並且相關實體的屬性名不是屬性名在'T'上。所以,基本上'SqlQuery'只能填充標量屬性,而不能導航屬性。但是我確定我不是。 – Slauma