我有一个名为Employee
的实体。它有一个名为CreatedById
的可空属性,可用作自身的引用。它必须为空,因为第一个记录,可能是管理员,不会有创建者。当初始化数据库时,我插入第一个Employee
对象时出现错误,我认为是因为我更新了与Fluent API的关系。代码如下:
Employee
类:
public class Employee : NullableInt32Entity, IUser<int> {
/// Omitted code that doesn't matter
}
NullableInt32Entity
继承自的Employee
类:
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.
}
}
最后,但并非最不重要的是我得到的例外:实体在&#39; DatabaseContext.Employees&#39;参加&#39; Equipment_CreatedBy&#39;关系。 0相关&#39; Equipment_CreatedBy_Source&#39;被找到。 1&#39; Equipment_CreatedBy_Source&#39;预计。
所以,我的问题是,我该如何解决这个问题?我今天第一次开始使用WithOptionalPrincipal()
和WithRequiredPrincipal()
,因为我意识到我并不关心从Employee
到任何其他对象的导航属性。我曾经在XCreated
中为每个其他对象都有一个Employee
集合导航属性,我意识到它们没有被暴露,因为我永远不会使用它们。因此我把它们剥离了,不得不使用上面的方法。
我感谢任何建议,并提前致谢!
答案 0 :(得分: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() {
}
}