实体框架6.1 - 的SaveChanges失败,可选校长关系 [英] Entity Framework 6.1 - SaveChanges fails with Optional Principal relationship
问题描述
我有一个名为员工
的实体。它有 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屋!