entity framework6.1 – SaveChanges因可选主体关系而失败

我有一个名为Employee的实体。 它有一个名为CreatedById的可空属性,它可以作为自身的引用。 它必须为null,因为第一个记录(可能是管理员)不会有创建者。 当初始化数据库时,我插入第一个Employee对象时会出现错误,我认为是因为我更新了与Fluent API的关系。 代码如下:

Employee类:

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

Employeeinheritance的NullableInt32Entity类:

 public class NullableInt32Entity : Entity, ICreatableEntity, IIndexableEntity { #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 { 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到任何其他对象的导航属性。 我XCreatedEmployee为每个其他对象都有一个XCreated集合导航属性,我意识到它们没有暴露,因为我永远不会使用它们。 因此我将它们剥离出来并且必须使用上述方法。

我感谢任何建议,并提前感谢!

好吧,事实certificate我是这里的白痴。 @KirillBestemyanov在他的一条评论中说,造成这个问题的是Equipment实体。 那是因为我正在阅读,但却没有理解错误信息。 我脑子里想到的是, Employee实体不是原因。 当我使用WithOptionalPrincipal()WithRequiredPrincipal()方法时,我也使用了错误的配置。 我不明白他们是如何运作的。

上面第二条评论中的代码实际上是正确的,但同样,我将它应用于错误的实体,这是没有错的,这就是为什么错误没有得到解决。 理解我出错的地方,我为我的整个DbContext实现进行了重写狂欢。 我现在有一个更强大的实现,其可维护性指数从60到76,我很高兴。

我实现了两个基类来帮助我解决我的问题,这是代码,以防有人对未来感兴趣:

Configuration_TEntity

 internal abstract class Configuration : EntityTypeConfiguration 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 : Configuration where TEntity : class, ICreatableEntity, ICreatableEntity, 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() { } }