[英]Entity Framework CodeFirst many to many return object null
我對流暢的api和實體框架(很多對很多的關系)有疑問。 當我嘗試從數據庫獲取數據時,對象Company
和pkdClassification
值為空。 值CompanyId
和PkdClassyficationId
正確返回。
語境
//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
CompanyId
和CompanyId
。
如果需要指定聯結表和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");
});
}
另一種方法是創建一個表示聯結表的實體(如您嘗試做的那樣),並與Classification
和Company
建立兩個一對多的關系,但是如果您不需要在聯結表中添加額外的列,則建議使用第一個變體。 如果遵循此變體,則表示聯結表的實體將如下所示:
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.