1

我对流利的 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; }
}

公司PKD分类

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


}
4

2 回答 2

3

在 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.

如果您需要指定联结表的名称和 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");
                        });

}

Classification另一种方法是创建一个表示联结表的实体(正如您尝试做的那样)并使用and建立两个一对多关系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);}
于 2015-04-12T13:15:59.147 回答
2

你能显示你用来获取值的查询吗?我认为这将与延迟加载的对象有关。如果您在请求导航属性之前执行 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; 
}
于 2015-04-12T12:27:52.543 回答