2014-04-19 72 views
0

我有一個名爲Employee的實體。它有一個名爲CreatedById的可以爲空的屬性,它可以用作自己的參考。它必須是空的,因爲第一個記錄(可能是管理員)不會有創建者。當數據庫正在初始化時,當插入第一個Employee對象時,我不斷收到錯誤,我認爲這是因爲我更新了與Fluent API的關係。代碼如下:實體框架6.1 - SaveChanges失敗,帶有可選主體關係

Employee類:

public class Employee : NullableInt32Entity, IUser<int> { 
    /// Omitted code that doesn't matter 
} 

NullableInt32EntityEmployee繼承:

public class NullableInt32Entity : 
    Entity, 
    ICreatableEntity<int?>, 
    IIndexableEntity<int> { 
    #region ICreatableEntity Members 
    public int? CreatedById { get; set; } 
    #endregion 

    #region IIndexableEntity Members 
    public int Id { get; set; } 
    #endregion 
} 

EmployeeConfiguration類,我認爲是造成問題的配置:

this.HasOptional(
    t => 
     t.CreatedBy).WithOptionalPrincipal(); 

DatabaseInitializer類:

internal sealed class DatabaseInitializer : DropCreateDatabaseIfModelChanges<DatabaseContext> { 
    protected override void Seed(
     DatabaseContext context) { 
     Employee creator = new Employee { 
      FirstName = "System", 
      IsActive = true, 
      LastName = "Administrator", 
      PasswordHash = "AIw9zIWiDnIesTaYhSjJhHJo5VYWCUV1rH0Oa0TaTriQXiDmXDBSq5y8Q0Zv3KUw/Q==" 
     }; 

     context.Employees.Add(creator); 
     context.SaveChanges(); 

     /// Additional seeds that depend on the one above as their creator. 
    } 
} 

而最後,但並非最不重要的例外,我得到:實體在「DatabaseContext.Employees」參加「Equipment_CreatedBy」的關係。找到0條相關'Equipment_CreatedBy_Source'。預計1'Equipment_CreatedBy_Source'。

所以,我的問題是,我該如何解決這個問題?我今天第一次開始使用WithOptionalPrincipal()WithRequiredPrincipal(),因爲我意識到我不在乎從Employee到任何其他對象的導航屬性。我曾在Employee中爲每個其他對象擁有一個XCreated集合導航屬性,我意識到他們沒有意義公開,因爲我永遠不會使用它們。因此,我將它們剝離出來,不得不使用上述方法。

我很欣賞任何建議,並提前致謝!

+0

您確定每個創作者實體(您在CreatedBy屬性中使用)只能在一個Employee實體中使用?看起來你應該使用一對多的關係。 –

+0

@KirillBestemyanov,是的,你是對的,那就是我想要的。我想我不太明白'WithXPrincipal()'。我嘗試用'this.HasOptional(t => t.CreatedBy).WithMany()。HasForeignKey(k => k.CreatedById)'替換它,但我仍然得到相同的異常。建議? – Gup3rSuR4c

+0

異常消息中有設備實體。你能展示它的代碼(類和配置)嗎? –

回答

0

好吧,原來我是這裏的白癡。 @KirillBestemyanov在他的一個評論中說,這是造成該問題的Equipment實體。那是因爲我正在閱讀而全部點擊了我的腦袋,但沒有理解錯誤信息。當我不知道時,我認爲Employee實體是它的原因。我在使用WithOptionalPrincipal()WithRequiredPrincipal()方法時也使用了錯誤的配置。我不瞭解他們如何運作。

上面第二條評論中的代碼實際上是正確的,但我又一次將它應用於錯誤的實體,這不是錯誤,這就是爲什麼錯誤沒有得到解決。瞭解我出錯的地方,我繼續爲我的整個DbContext實施進行重寫。我現在有一個更強大的實施,其可維護性指數從60到76,我很高興。

我實現了兩個基類這幫助我解決我的問題,這裏是萬一有人的代碼是有意在未來:

Configuration_TEntity

internal abstract class Configuration<TEntity> : 
    EntityTypeConfiguration<TEntity> 
    where TEntity : class, ICreatableEntity, IRemovableEntity, new() { 
    protected virtual void Configure() { 
     this.ConfigureCreatableProperties(); 
     this.ConfigureRemovableProperties(); 
     this.ConfigureProperties(); 
     this.ConfigureCreatableRelationships(); 
     this.ConfigureRemovableRelationships(); 
     this.ConfigureRelationships(); 
    } 

    #region Property Configurations 
    protected virtual void ConfigureCreatableProperties() { 
     this.Property(
      p => 
       p.CreatedDateTime).HasColumnType("datetime2"); 
    } 

    protected virtual void ConfigureRemovableProperties() { 
     this.Property(
      p => 
       p.RemovedDateTime).HasColumnType("datetime2"); 
    } 

    protected abstract void ConfigureProperties(); 
    #endregion 

    #region Relationship Configurations 
    protected abstract void ConfigureCreatableRelationships(); 

    protected virtual void ConfigureRemovableRelationships() { 
     this.HasOptional(
      t => 
       t.RemovedBy).WithMany().HasForeignKey(
      k => 
       k.RemovedById); 
    } 

    protected abstract void ConfigureRelationships(); 
    #endregion 
} 

Configuration_TEntity_TCreatedByKey

internal class Configuration<TEntity, TCreatedByKey> : 
    Configuration<TEntity> 
    where TEntity : class, ICreatableEntity, ICreatableEntity<TCreatedByKey>, IRemovableEntity, new() 
    where TCreatedByKey : struct { 
    protected override void ConfigureCreatableRelationships() { 
     this.HasRequired(
      t => 
       t.CreatedBy).WithMany().HasForeignKey(
      k => 
       k.CreatedById); 
    } 

    protected override void ConfigureProperties() { 
    } 

    protected override void ConfigureRelationships() { 
    } 
}