2

我有一個數據庫與實體框架5 RC(與Fluent API)現在工作,但我似乎無法得到一個特定的關係工作。過去的幾個晚上,我正在努力工作,這讓我瘋狂。EF Fluent API多對一的關係,導航屬性不提取

它是存在以下關係:

Link to the database diagram

正如你所看到的,我有一個Exercise這是關係到一個ExerciseType。問題是,導航屬性Exercise.ExerciseType未加載。我所做的關係如下:

EntityTypeConfiguration<Exercise> 
... 
this.HasRequired(ex => ex.ExerciseType) 
    .WithMany(exType => exType.Exercises) 
    .HasForeignKey(ex => ex.ExerciseTypeId); 

問題是,我沒有錯誤的谷歌。實體被提取,但Exercise對象上的相關EntityType屬性永遠不會被提取。

我正在使用以下查詢來強制獲取ExerciseType,但這似乎並沒有使其工作。

List<Exercise> exs = db.Exercises.Include(t => t.ExerciseType).ToList(); 

是否有一些與我創建的關係有問題?或者,數據庫配置可能有問題嗎?

代碼實體:

public class ExerciseType 
{ 
    public int ExerciseTypeId { get; set; } 
    public string ExerciseTypeName { get; set; } 
    public System.DateTime CreatedOn { get; set; } 
    public Nullable<int> CreatedBy { get; set; } 
    public Nullable<System.DateTime> ModifiedOn { get; set; } 
    public Nullable<int> ModifiedBy { get; set; } 
    public virtual ICollection<Exercise> Exercises { get; set; } 
} 

public class Exercise 
{ 
    public Exercise() 
    { 
     this.ExerciseTemplateMembers = new List<ExerciseTemplateMember>(); 
     this.TrainingSchemeMembers = new List<TrainingSchemeMember>(); 
     this.ExerciseType = new ExerciseType(); 
    } 

    public int ExerciseId { get; set; } 
    public int ExerciseTypeId { get; set; } 
    public string ExerciseName { get; set; } 
    public string DescriptionHowTo { get; set; } 
    public string DescriptionResult { get; set; } 
    public byte[] ExerciseImage1 { get; set; } 
    public byte[] ExerciseImage2 { get; set; } 
    public string ExerciseVideoUrl { get; set; } 
    public bool Enabled { get; set; } 
    public System.DateTime CreatedOn { get; set; } 
    public Nullable<int> CreatedBy { get; set; } 
    public Nullable<System.DateTime> ModifiedOn { get; set; } 
    public Nullable<int> ModifiedBy { get; set; } 
    public virtual ICollection<ExerciseTemplateMember> ExerciseTemplateMembers { get; set; } 
    public virtual ICollection<TrainingSchemeMember> TrainingSchemeMembers { get; set; } 
    public virtual ExerciseType ExerciseType { get; set; } 
} 

    public ExerciseMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ExerciseId); 

     // Properties 
     this.Property(t => t.ExerciseName) 
      .HasMaxLength(50); 

     this.Property(t => t.DescriptionHowTo) 
      .HasMaxLength(250); 

     this.Property(t => t.DescriptionResult) 
      .HasMaxLength(250); 

     this.Property(t => t.ExerciseVideoUrl) 
      .HasMaxLength(200); 

     // Table & Column Mappings 
     this.ToTable("Exercise"); 
     this.Property(t => t.ExerciseId).HasColumnName("ExerciseId"); 
     this.Property(t => t.ExerciseTypeId).HasColumnName("ExerciseTypeId"); 
     this.Property(t => t.ExerciseName).HasColumnName("ExerciseName"); 
     this.Property(t => t.DescriptionHowTo).HasColumnName("DescriptionHowTo"); 
     this.Property(t => t.DescriptionResult).HasColumnName("DescriptionResult"); 
     this.Property(t => t.ExerciseImage1).HasColumnName("ExerciseImage1"); 
     this.Property(t => t.ExerciseImage2).HasColumnName("ExerciseImage2"); 
     this.Property(t => t.ExerciseVideoUrl).HasColumnName("ExerciseVideoUrl"); 
     this.Property(t => t.Enabled).HasColumnName("Enabled"); 
     this.Property(t => t.CreatedOn).HasColumnName("CreatedOn"); 
     this.Property(t => t.CreatedBy).HasColumnName("CreatedBy"); 
     this.Property(t => t.ModifiedOn).HasColumnName("ModifiedOn"); 
     this.Property(t => t.ModifiedBy).HasColumnName("ModifiedBy"); 

     // Relationships 
     this.HasRequired(ex => ex.ExerciseType) 
      .WithMany(exType => exType.Exercises) 
      .HasForeignKey(ex => ex.ExerciseTypeId); 
    } 

    public ExerciseTypeMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ExerciseTypeId); 

     // Properties 
     this.Property(t => t.ExerciseTypeName) 
      .IsRequired() 
      .HasMaxLength(50); 

     // Table & Column Mappings 
     this.ToTable("ExerciseType"); 
     this.Property(t => t.ExerciseTypeId).HasColumnName("ExerciseTypeId"); 
     this.Property(t => t.ExerciseTypeName).HasColumnName("ExerciseTypeName"); 
     this.Property(t => t.CreatedOn).HasColumnName("CreatedOn"); 
     this.Property(t => t.CreatedBy).HasColumnName("CreatedBy"); 
     this.Property(t => t.ModifiedOn).HasColumnName("ModifiedOn"); 
     this.Property(t => t.ModifiedBy).HasColumnName("ModifiedBy"); 
    } 
+0

有在你的代碼中沒有錯。奇怪的問題。數據庫中的「ExerciseTypeId」是否是不可空的,並且你是否有強制的外鍵約束來處理DB中的關係?練習是否參考數據庫中現有的練習類型? – Slauma

回答

2

刪除這條線從Exercise構造:

this.ExerciseType = new ExerciseType(); 

實例化在默認構造方法的導航參考性質導致各種奇怪的問題,像這樣的例子:What would cause the Entity Framework to save an unloaded (but lazy loadable) reference over existing data?或者這樣:EF 4.1 Code First: Why is EF not setting this navigation property?

+0

這確實解決了這個問題。當我將「ICollection」類型作爲屬性建立關係時,我認爲這沒有害處。現在我知道我可以使用ICollections,並且不能使用單個實體。或者我還需要刪除其他兩個初始化?因爲據我所知他們工作正常。感謝您的幫助和見解。 – Roet

+0

@Roet:創建空集合是沒有問題的。 – Slauma

0

能否請您提供EntityType類的代碼?今天當我忘記製作房產(ExerciseType您的情況)時,我與EF 4.3.1有同樣的問題虛擬。如果不是這樣,請提供班級的代碼。

如果您使用延遲加載功能,則您的實體必須具有標記爲虛擬的導航屬性。 EF會生成從您的實體繼承的代理類,如果該屬性不是虛擬的,則派生類無法提供該屬性的自己實現(應該會延遲加載相關對象/集合的實現)。

+0

我有他們標記虛擬,因爲我知道這一點。但是你有一個好點。我將實體的代碼添加到問題中,您可能會注意到其他問題。 – Roet