EF6:返回空集合的多对多关系

时间:2018-03-30 01:23:19

标签: c# entity-framework entity-framework-6 ef-code-first

过去3个小时我一直想弄清楚这一点,我确定我错过了一些非常明显的东西...

以下是型号代码:

[Table("company")]
public partial class company
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public company()
    {
        job = new HashSet<job>();
        contact = new HashSet<contact>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int companyId { get; set; }

    [Required]
    [StringLength(255)]
    public string name { get; set; }

    [StringLength(255)]
    public string address { get; set; }

    [StringLength(255)]
    public string locality { get; set; }

    [StringLength(255)]
    public string city { get; set; }

    [StringLength(100)]
    public string state { get; set; }

    [StringLength(16)]
    public string postalCode { get; set; }

    [StringLength(2)]
    public string country { get; set; }

    [StringLength(16)]
    public string phone { get; set; }

    [StringLength(63)]
    public string email { get; set; }

    [StringLength(127)]
    public string website { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<job> job { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<contact> contact { get; set; }
}

[Table("contact")]
public partial class contact
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public contact()
    {
        this.company = new HashSet<company>();
    }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int contactId { get; set; }

    [Required]
    [StringLength(64)]
    public string firstName { get; set; }

    [Required]
    [StringLength(64)]
    public string lastName { get; set; }

    [StringLength(1)]
    public string middleInitial { get; set; }

    public string title { get; set; }

    [StringLength(18)]
    public string phoneNumber { get; set; }

    [StringLength(128)]
    public string emailAddress { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<company> company { get; set; }
}

[Table("job")]
public class job
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public job()
    {
        company = new HashSet<company>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int jobId { get; set; }

    public string jobTitle { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<company> company { get; set; }

}

OnModelCreating我有这个:

modelBuilder.Entity<company>()
    .HasMany(e => e.job)
    .WithMany(e => e.company)
    .Map(m => m.ToTable("company_job", "dbo").MapLeftKey("companyId").MapRightKey("jobId"));

modelBuilder.Entity<company>()
    .HasMany(e => e.contact)
    .WithMany(e => e.company)
    .Map(m => m.ToTable("company_contact", "dbo").MapLeftKey("companyId").MapRightKey("contactId"));

我已在数据库端检查了以下所有内容:

  • 所有三个主表都存在并匹配模型column-for-column。
  • 存在与桥接表的所有外键关系。
  • 两个桥接表都有一个由两列组成的复合主键。
  • 两个桥接表的名称都与Map方法参数匹配,桥接表中的列也是如此。
  • 数据库中包含的相应数据应导致jobcontact个实体显示在所有company个实体下。
  • 手动编写的数据库查询可以成功生成预期的数据。

然而:

ctx.company.Where(x => x.companyId == 300).job.Count()

始终返回0。尝试:

ctx.company.Where(x => x.companyId == 300).job.FirstOrDefault()

返回null

我尝试在上下文中设置日志记录:

Database.Log = msg => System.Diagnostics.Debug.WriteLine(msg);

我注意到,发送到数据库的唯一查询是针对company表的。它没有进行连接查询。它甚至从未触及jobcontact表或桥接表。它只是使用正确的company子句对WHERE表进行单个查询,但永远不会更进一步。

只是为了踢,我尝试颠倒.Map调用中字段的顺序,但这没有效果。 (换句话说:.Map(m => m.ToTable("company_job", "dbo").MapLeftKey("jobId").MapRightKey("companyId"))没有改变。)

好的,我错过了什么?

1 个答案:

答案 0 :(得分:1)

... ACK

在上下文构造函数中是这样的:

base.Configuration.ProxyCreationEnabled = false;

我删除了它,现在似乎工作了!

(我继承了这段代码,所以这里的教训是:永远不要假设你继承的代码完全符合认为它做的那样!)