Entity Framework CodeFirst 多对多 return 对象 null
Entity Framework CodeFirst many to many return object null
我对流利的 api 和 entity framework(多对多关系)有疑问。当我尝试从数据库中获取数据时,对象 Company
和 pkdClassification
上的值为空。值 CompanyId
和 PkdClassyficationId
returns 正确。
上下文
//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; }
}
你能展示一下你用来获取值的查询吗?我认为这将与被延迟加载的对象有关。如果您在请求导航 属性 之前执行 ToList() ,那么这些值将为空。您必须通过在查询中添加以下内容来强制包含该值:
.Include(x => x.Company)
等等,对于您想要的每个对象,或者在对象仍然存在时请求值。即在您执行 ToList() 之前;这里有更详细的解释:https://msdn.microsoft.com/en-gb/library/vstudio/bb738633%28v=vs.100%29.aspx
根据您在下方的评论,FirstOrDefault() 将执行查询,因此在此之后无法再填充导航属性。我会试试这个(提供 dbContext.company 是一组 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;
}
在 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 将创建第三个连接 table、ClassificationCompanies
,它将包含两个 table 的主键,即。 ClassificationId
& CompanyId
.
如果您需要指定联结的名称 table 和 FK 列,那么您可以配置关系覆盖上下文中的 OnModelCreating
方法并使用 Fluent 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");
});
}
另一种方法是创建一个代表连接点 table 的实体(正如您尝试做的那样)并与 Classification
和 Company
建立两个一对多关系,但是如果您不需要向联结点添加额外的列 table,建议使用第一种变体。如果您遵循此变体,表示联结 table 的实体将如下所示:
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);}
我对流利的 api 和 entity framework(多对多关系)有疑问。当我尝试从数据库中获取数据时,对象 Company
和 pkdClassification
上的值为空。值 CompanyId
和 PkdClassyficationId
returns 正确。
上下文
//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; }
}
你能展示一下你用来获取值的查询吗?我认为这将与被延迟加载的对象有关。如果您在请求导航 属性 之前执行 ToList() ,那么这些值将为空。您必须通过在查询中添加以下内容来强制包含该值:
.Include(x => x.Company)
等等,对于您想要的每个对象,或者在对象仍然存在时请求值。即在您执行 ToList() 之前;这里有更详细的解释:https://msdn.microsoft.com/en-gb/library/vstudio/bb738633%28v=vs.100%29.aspx
根据您在下方的评论,FirstOrDefault() 将执行查询,因此在此之后无法再填充导航属性。我会试试这个(提供 dbContext.company 是一组 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;
}
在 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 将创建第三个连接 table、ClassificationCompanies
,它将包含两个 table 的主键,即。 ClassificationId
& CompanyId
.
如果您需要指定联结的名称 table 和 FK 列,那么您可以配置关系覆盖上下文中的 OnModelCreating
方法并使用 Fluent 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");
});
}
另一种方法是创建一个代表连接点 table 的实体(正如您尝试做的那样)并与 Classification
和 Company
建立两个一对多关系,但是如果您不需要向联结点添加额外的列 table,建议使用第一种变体。如果您遵循此变体,表示联结 table 的实体将如下所示:
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);}