簡體   English   中英

實體框架CodeFirst多對多返回對象null

[英]Entity Framework CodeFirst many to many return object null

我對流暢的api和實體框架(很多對很多的關系)有疑問。 當我嘗試從數據庫獲取數據時,對象CompanypkdClassification值為空。 CompanyIdPkdClassyficationId正確返回。

語境

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

pkd分類

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

companyPkd分類

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


}

在Code First中映射多對多關系的最佳方法是:

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

默認情況下,Code-First將創建第三個聯接表, ClassificationCompanies ,它將由兩個表的PK組成。 ClassificationId CompanyIdCompanyId

如果需要指定聯結表和FK列的名稱,則可以使用Fluent Api在上下文中配置覆蓋OnModelCreating方法的關系:

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

您可以顯示用於獲取值的查詢嗎? 我認為這將與延遲加載的對象有關。 如果在請求導航屬性之前執行ToList(),則這些值將為null。 您必須通過在查詢中添加此值來強制包含該值:

.Include(x => x.Company)

依此類推,為每個您想要或在對象仍然存在時請求其值的對象。 即在您執行ToList()之前; 此處詳細說明: https : //msdn.microsoft.com/zh-cn/library/vstudio/bb738633%28v=vs.100%29.aspx

根據您在下面的評論,FirstOrDefault()將執行查詢,因此在此之后不再可以填充導航屬性。 我會嘗試這樣做(提供dbContext.company是一組Company對象):

為System.Data.Entity添加using;

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM