我有一个名为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

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

2回复

实体框架SaveChanges()不起作用

调用用于更新的API时出现问题,并且savechanges()无法正常工作(数据未更新)。 但是,当我添加Thread.Sleep(1000); 数据正确更新。 工作方法 失败方法 编辑 我已经意识到从客户端同时调用两个API。 此外,在同一个表这两个API
1回复

实体框架SaveChanges()错误?

我有一个CRUD应用程序,处理两个对象,卡和日志。 用户创建,编辑或删除卡时,将在数据库的日志表中创建一个新的日志记录。 用户创建卡时,日志记录的NewCard值为JSON数据,而OldCard值为null。 当用户删除卡时,日志记录的OldCard值为JSON数据,而NewCard为空。
1回复

实体框架SaveChanges异步

我目前正在研究审计跟踪功能并使用实体框架。 当前代码有效,但是需要很长时间才能运行。 我当时想在保存更改后移动审核跟踪构建并使其异步 我曾尝试使用async-await,但遇到对象已处置的问题。 我不是很习惯线程/异步调用。 有没有一种方法可以执行“部分”返回,即父
2回复

实体框架SaveChanges错误

我不太确定这是否是错误,但对我来说很像。 我首先使用Entity Framework 6.1.1代码,并且具有以下类: 当我尝试使用以下代码更新用户密码时,出现错误: 错误:一个或多个实体的验证失败。 有关更多详细信息,请参见'EntityValidationErrors'属
2回复

实体框架中的可选一对多关系

我在获取可选的一对多关系上工作时遇到问题。 我的模型是: 我想给一个Person分配零个或一个Department 。 当分配时, Person应在显示Members的的-列出Department 。 我正在使用Fluent API配置Person ,如下所示: 还
1回复

db.SaveChanges的System.OutOfMemoryException实体框架6

我正在运行将事件插入具有实体框架的数据库的批处理作业。 总大小有所不同,但大约有350万个事件是正常的。 此列表分为60-500k个事件组,然后添加到数据库中。 但是,当添加了大约一百万个事件时,我得到System.OutOfMemoryException并且必须重新开始。 因此,要
1回复

实体框架从saveChanges中的contex获取用户

我的解决方案中有两个项目,UI作为mvc,第一个用于实体模型代码的类项目。 我的模型中有多个实体,但是现在我需要通过新的审计字段来扩展它们,并在其中保存谁更改了实体。 我添加了新界面 并尝试以这种方式扩展SaveChanges 但是如何在这里获取用户名? 我不能使用任何ht
3回复

实体框架:SaveChanges返回的对象没有子对象之后

当我在数据库中保存一个对象然后检索保存的对象时,它将显示所有空子对象。 我使用Entity Framework 6,并且一直使用下面的示例中所示的查询,并且始终可以正常工作,但是我不明白为什么该查询显示空子对象。
1回复

克隆实体失败,并在SaveChanges()上违反了主键

我正在尝试复制此处描述的实体。 在我的entry-wrapper基类中,我具有以下代码来复制/克隆实体。 在我对具体实体调用Clone方法之后,它的新主键也设置为给定值newPrimaryKey 。 当我在基础上下文上调用SaveChanges()时,就会出现问题。 然后抛
2回复

在实体框架6.1中模拟DbContext

我发现许多示例(显然)显示了使用EF 6模拟DbContext的清晰工作示例,但是,似乎没有一个对我有用,我也不完全知道为什么。 这是设置模拟的我的单元测试代码; 然后调用我正在测试的服务; 由于基础DbSet始终为null,因此将引发NullReferenceExcept