实体框架6.1 - 的SaveChanges失败,可选校长关系 [英] Entity Framework 6.1 - SaveChanges fails with Optional Principal relationship

查看:114
本文介绍了实体框架6.1 - 的SaveChanges失败,可选校长关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为员工的实体。它有 CreatedById 称为一个可空属性,它被用来作为参考回自己。它必须是空,因为第一个记录,想必管理员,会不会有一个创造者。当数据库正在初始化,我不断收到一个错误,当第一个员工插入对象时,我推测是因为我更新了流利的API的关系的方式。代码如下:

I have an entity called Employee. It has a nullable property called CreatedById which is used as a reference back to itself. It has to be null since the very first record, presumably the administrator, won't have a creator. When by database is being initialized, I keep getting an error when the first Employee object is inserted which I presume is because of the way I updated the relationships with the Fluent API. Code is as follows:

员工类:

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



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 类,我认为导致此问题:

The configuration in the EmployeeConfiguration class that I think is causing the issue:

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的关系。有关Equipment_CreatedBy_Source 0被发现了。 1'Equipment_CreatedBy_Source'的预期。

And last, but not least the exception I'm getting: Entities in 'DatabaseContext.Employees' participate in the 'Equipment_CreatedBy' relationship. 0 related 'Equipment_CreatedBy_Source' were found. 1 'Equipment_CreatedBy_Source' is expected.

所以,我的问题是,我该如何解决这个问题?我开始使用 WithOptionalPrincipal() WithRequiredPrincipal()今天是第一次,因为我意识到我不在乎从员工的导航性能,其他任何对象。我曾经在雇员 XCreated 集合导航属性对于所有其他对象,我意识到,他们是毫无意义的揭露因为我永远不会使用它们。因此,我剥离出来,只好用上面的方法。

So, my question is, how do I fix this? I started using WithOptionalPrincipal() and WithRequiredPrincipal() today for the first time because I realized I don't care for navigational properties from Employee to any of the other objects. I used to have a XCreated collection navigation property in Employee for every other object and I realized that they were pointless to expose since I'll never use them. Thus I stripped them out and had to use the methods above.

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

I appreciate any suggestions, and thanks in advance!

推荐答案

好了,原来我在这里很白痴。 @KirillBestemyanov在他的评论人说,这是这是造成这一问题的设备实体。这时候,这一切在我的头上点击,因为我读书,但不理解的错误消息。我曾在我的头上了员工实体是因为当它不是。我也用我所用的 WithOptionalPrincipal() WithRequiredPrincipal()方法时,错误的配置。上面我不理解他们是如何运作。

Ok, so it turns out I'm the idiot here. @KirillBestemyanov in one of his comments said that it was the Equipment entity that was causing the issue. That's when it all clicked in my head because I was reading, but not understanding the error message. I had it in my head that the Employee entity was the cause when it wasn't. I was also using the wrong configuration when I was using the WithOptionalPrincipal() and WithRequiredPrincipal() methods. I wasn't understanding how they functioned.

在第二个评论中的代码,其实是正确的,但同样,我是把它应用到WASN错误的实体T对于故障这是为什么错误没有得到解决。理解,我已经走了错了,我去了一个大礼包,重写我的整个的DbContext 的实施。我现在有一个更强大的执行和可维护性指数从60到76,我很高兴。

The code in the second comment above was in fact correct, but again, I was applying it to the wrong entity which wasn't at fault which is why the error wasn't getting resolved. Understanding where I had gone wrong, I went on a rewrite spree for my entire DbContext implementation. I now have a much more robust implementation and its Maintainability Index went from 60 to 76, which I'm happy about.

我实现了两个基类这帮助我解决我的问题,这里万一有人的代码是有兴趣在未来的:

I implemented two base classes which helped me resolve my issues, here's the code in case someone is interested in the future:

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() {
    }
}

这篇关于实体框架6.1 - 的SaveChanges失败,可选校长关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆