2015-04-12 80 views
1

我有流利的API和實體框架(關係多對多)的問題。當我試圖從數據庫中獲取數據時,在對象CompanypkdClassification上有空值。價值CompanyIdPkdClassyficationId正常返回。實體框架CodeFirst多對多返回對象null

上下文

//in contrstructor set 
// this.Configuration.LazyLoadingEnabled = true; 

     .Entity<CompanyPkdClassification>() 
     (c => new { c.PkdClassyficationId, c.CompanyId }); 

     modelBuilder.Entity<Company>() 
      .HasMany(c => c.companyPkdClassification) 
      .WithRequired() 
      .HasForeignKey(c => c.CompanyId); 

     modelBuilder.Entity<PkdClassification>() 
      .HasMany(c => c.companyPkdClassification) 
      .WithRequired() 
      .HasForeignKey(c => c.PkdClassyficationId);} 

pkdClassification

public class PkdClassification 
{ 
    [Key] 
    [DisplayName("Id")] 
    public int id { get; set; } 
    ... 
    public virtual ICollection<CompanyPkdClassification> companyPkdClassification { get; set; } 
} 

companyPkdClassification

public class CompanyPkdClassification 
{ 
    [ForeignKey("company")] 
    public int CompanyId { get; set; } 

    [ForeignKey("pkdClassification")] 
    public int PkdClassyficationId { get; set; } 

    public virtual ICollection<Company> company { get; set; } 
    public virtual ICollection<PkdClassification> pkdClassification { get; set; } 
} 

而最後一個公司

public class Company : baseModel 
{ 
    ... 
virtual ICollection<CompanyPkdClassification> companyPkdClassification { get; set; } 


} 

回答

2

映射在代碼中首先一個多一對多的關係,最好的辦法是這樣的:

public class Classification 
{ 
    [Key] 
    [DisplayName("Id")] 
    public int id { get; set; } 
    ... 
    public virtual ICollection<Company> Companies{ get; set; } 
} 

public class Company 
{ 
    public int Id { get; set; } 
    ... 
    public virtual ICollection<Classification> Classifications { get; set; } 
} 

默認情況下,代碼首先將創建一個第三結合表,ClassificationCompanies其中將包括PK兩個表,即。 ClassificationId & CompanyId

如果需要指定結點表和FK列的名字,那麼你可以配置的關係,覆蓋在你的上下文OnModelCreating方法的使用流利的API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 

    modelBuilder.Entity<Classification>() 
       .HasMany<Company>(s => s.Companies) 
       .WithMany(c => c.Classifications) 
       .Map(cs => 
         { 
          cs.MapLeftKey("ClassificationId"); 
          cs.MapRightKey("CompanyId"); 
          cs.ToTable("ClassificationCourses"); 
         }); 

} 

另一種方法是創建一個代表聯結表的實體(如您試圖執行的),並建立與ClassificationCompany的兩個一對多關係,但如果您不需要向聯結表添加額外的列,則建議使用第一個變體。如果按照這個變型,實體代表結合表會是這樣:

public class CompanyPkdClassification 
{ 
    public int CompanyId { get; set; } 

    public int PkdClassyficationId { get; set; } 

    public virtual Company Company { get; set; } 
    public virtual Classification Classification { get; set; } 
} 

而且配置:

 modelBuilder.Entity<CompanyPkdClassification>().HasKey(c => new { c.PkdClassyficationId, c.CompanyId }); 

    modelBuilder.Entity<Company>() 
     .HasMany(c => c.companyPkdClassification) 
     .WithRequired(cc=>Company) 
     .HasForeignKey(c => c.CompanyId); 

    modelBuilder.Entity<PkdClassification>() 
     .HasMany(c => c.companyPkdClassification) 
     .WithRequired(cc=>Classification) 
     .HasForeignKey(c => c.PkdClassyficationId);} 
+0

我選擇了第二個變體,它的功能非常完美。非常感謝 :) – michal

1

你能證明你正在使用得到的值查詢?我認爲這將與被加載的對象有關。如果您在請求導航屬性之前執行了ToList(),那麼這些值將爲空。你必須在你的查詢中添加這種要麼強制值包括:

.Include(x => x.Company) 

等爲每個對象你想要或要求值,而該對象是否仍然活着。即在執行ToList()之前;在此處更詳細地解釋:https://msdn.microsoft.com/en-gb/library/vstudio/bb738633%28v=vs.100%29.aspx

根據您的評論,FirstOrDefault()將執行查詢,因此不能再在此點之後填充導航屬性。我會試試這個(提供dbContext.company是一組公司對象):

添加使用System.Data.Entity;

public Company getCompany(int id) { 
    Company data = dbContext.company.Include(x => x.companyPkdClassification .Select(y => y.company)).Include(x => x.companyPkdClassification .Select(y => y.pkdClassification)).Where(i => i.id == id).FirstOrDefault(); 
    return data; 
} 
+0

只是簡單: 'code' 上市公司getCompany(INT ID ) { Company data = dbContext.company 。Where(i => i.id == id) .FirstOrDefault(); 返回數據; } 'code' – michal

+0

不錯,謝謝Dhunt! – DigaoParceiro