C# 同一类型的一对一关系实体
我是ASP.NetCore和EF Core的新手 我很难想出如何处理这种情况: 我有一个可用研究的列表,每个研究都有一个可用研究的列表。但是,一个阶段也可能取决于前一阶段(但不是强制性的),同样的情况也发生在研究中,一项研究可能取决于前一项研究。以下是模型类: 业务对象:C# 同一类型的一对一关系实体,c#,asp.net-core,ef-core-2.2,C#,Asp.net Core,Ef Core 2.2,我是ASP.NetCore和EF Core的新手 我很难想出如何处理这种情况: 我有一个可用研究的列表,每个研究都有一个可用研究的列表。但是,一个阶段也可能取决于前一阶段(但不是强制性的),同样的情况也发生在研究中,一项研究可能取决于前一项研究。以下是模型类: 业务对象: public class BusinessObject : IBusinessObject { #region Constructors public BusinessObject()
public class BusinessObject : IBusinessObject
{
#region Constructors
public BusinessObject()
{
Id = Guid.NewGuid().ToString();
}
public BusinessObject(string name) : this()
{
Name = name;
}
#endregion
#region IBusinessObject implementation
public string Id { get; set; }
public string Name { get; set; }
#endregion
}
public class AvailableStudy : BusinessObject
{
#region Constructors
public AvailableStudy() : base()
{
Stages = new List<AvailableStage>();
}
public AvailableStudy(string name) : base(name)
{
Stages = new List<AvailableStage>();
}
#endregion
[ForeignKey("DependsOn")]
public string DependsOnId { get; set; }
#region Lazy-Load Properties
public virtual List<AvailableStage> Stages { get; set; }
public virtual AvailableStudy DependsOn { get; set; }
#endregion
}
public class AvailableStage : BusinessObject
{
#region Constructors
public AvailableStage() : base()
{
}
public AvailableStage(string name) : base(name)
{
}
public AvailableStage(string name, AvailableStudy study) : base(name)
{
Study = study;
}
#endregion
#region Properties
[Required]
public string StudyId { get; set; }
public double Percentage { get; set; }
public int Duration { get; set; }
[ForeignKey("DependsOn")]
public string DependsOnId { get; set; }
#endregion
#region Lazy-Load Properties
public virtual AvailableStage DependsOn { get; set; }
[ForeignKey("StudyId")]
public virtual AvailableStudy Study { get; set; }
#endregion
}
可用性研究:
public class BusinessObject : IBusinessObject
{
#region Constructors
public BusinessObject()
{
Id = Guid.NewGuid().ToString();
}
public BusinessObject(string name) : this()
{
Name = name;
}
#endregion
#region IBusinessObject implementation
public string Id { get; set; }
public string Name { get; set; }
#endregion
}
public class AvailableStudy : BusinessObject
{
#region Constructors
public AvailableStudy() : base()
{
Stages = new List<AvailableStage>();
}
public AvailableStudy(string name) : base(name)
{
Stages = new List<AvailableStage>();
}
#endregion
[ForeignKey("DependsOn")]
public string DependsOnId { get; set; }
#region Lazy-Load Properties
public virtual List<AvailableStage> Stages { get; set; }
public virtual AvailableStudy DependsOn { get; set; }
#endregion
}
public class AvailableStage : BusinessObject
{
#region Constructors
public AvailableStage() : base()
{
}
public AvailableStage(string name) : base(name)
{
}
public AvailableStage(string name, AvailableStudy study) : base(name)
{
Study = study;
}
#endregion
#region Properties
[Required]
public string StudyId { get; set; }
public double Percentage { get; set; }
public int Duration { get; set; }
[ForeignKey("DependsOn")]
public string DependsOnId { get; set; }
#endregion
#region Lazy-Load Properties
public virtual AvailableStage DependsOn { get; set; }
[ForeignKey("StudyId")]
public virtual AvailableStudy Study { get; set; }
#endregion
}
最后,我的上下文类的onmodel创建:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AvailableStudy>().ToTable("AvailableStudies");
modelBuilder.Entity<AvailableStudy>().HasMany(i => i.Stages).WithOne(c => c.Study);
modelBuilder.Entity<AvailableStudy>().HasOne(i => i.DependsOn);
modelBuilder.Entity<AvailableStage>().ToTable("AvailableStages");
modelBuilder.Entity<AvailableStage>().HasOne(i => i.Study).WithMany(u => u.Stages);
modelBuilder.Entity<AvailableStage>().HasOne(i => i.DependsOn);
}
然后,我将这些研究添加到DBContext类中的适当DBSet中,当我尝试保存更改时,抛出一个异常,该异常表示:
SqlException:INSERT语句与外键同一表约束“FK\u AvailableStates\u AvailableStates\u DependsOnId”冲突。冲突发生在数据库“Latendesamples”、表“dbo.AvailableStates”、列“Id”中。
声明已终止
我真的不明白发生了什么事
谢谢你的帮助
完整的异常结果是:
Microsoft.EntityFrameworkCore.DbUpdateException
HResult=0x80131500
Message=An error occurred while updating the entries. See the inner exception for details.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at LabManager.DataModel.Data.DbSeeder.CreateStudiesWithStages(ApplicationDbContext dbContext) in W:\LabManager\DataModel\src\Data\DbSeeder.cs:line 113
at LabManager.DataModel.Data.DbSeeder.Seed(ApplicationDbContext dbContext, RoleManager`1 roleManager, UserManager`1 userManager, IHostingEnvironment env) in W:\LabManager\DataModel\src\Data\DbSeeder.cs:line 22
at LabManagerWebPage.Extensions.ServiceExtensions.ConfigureDBContext(IApplicationBuilder app, IHostingEnvironment env) in W:\LabManager\LabManagerWebPage\Extensions\ServiceExtensions.cs:line 156
at LabManagerWebPage.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in W:\LabManager\LabManagerWebPage\Startup.cs:line 107
Inner Exception 1:
SqlException: The INSERT statement conflicted with the FOREIGN KEY SAME TABLE constraint "FK_AvailableStages_AvailableStages_DependsOnId". The conflict occurred in database "LateAndesSamples", table "dbo.AvailableStages", column 'Id'.
The statement has been terminated.
你的问题是基类。它必须是抽象的。否则,它将创建关系继承,EF Core支持的唯一策略是每个层次的表,也称为单表继承。这意味着对于像
BusinessObject
这样的看似全局的基类,您最终将得到一个巨大的表,其中包含所有其他类型。换句话说,就是一团糟
通过将其抽象化,派生类型将继承该行为,但它们仍将各自获得自己的表。我解决了
解析JSON文件后,我调用了以下方法:
//availables is a list of availiables studies generated after parsing json file
dbContext.AvailableStudies.AddRange(availables);
dbContext.SaveChanges();
但当我详细查看时,没有依赖项的阶段包含DependsOnId属性上的空字符串,而不是null。将空字符串替换为null后,它可以正常工作 谢谢你,安瑟!很抱歉出现了noob问题,但当调用“modelBuilder.Entity().ToTable(“AvailableStudies”);”等时,OnModelCreating方法无法解决此问题。无论如何,我已经听从了您的建议。再次感谢你!