我有一个名为Employee的实体。 它具有一个称为CreatedById的可空属性,该属性用作对自身的引用。 由于第一条记录(大概是管理员)没有创建者,因此必须为null。 当按数据库初始化时,插入第一个Employee对象时,我总是收到错误消息,我认为这是因为我使用Fluent API更新关系的方式。 代码如下:

Employee类:

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

Employee继承自的NullableInt32Entity类:

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到其他任何对象的导航属性。 XCreatedEmployee为每个其他对象都拥有一个XCreated集合导航属性,但我意识到它们是毫无意义的,因为我永远不会使用它们。 因此,我将它们剥离,不得不使用上面的方法。

我感谢任何建议,并在此先感谢!

===============>>#1 票数: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() {
    }
}

  ask by Gup3rSuR4c translate from so

未解决问题?本站智能推荐: