[英]One to one relationship entities of same type
我是ASP.NetCore和EF Core的新手。
我很难弄清楚如何处理这种情况:
我有一个AvailableStudy列表,每个研究都有一个AvailableStage列表。 而且,一个阶段可以取决于先前的阶段(但不是强制性的),并且研究也是如此,一项研究可以取决于先前的研究。 这是模型类:
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
}
AvailableStudy:
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
}
AvailableStage:
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
}
最后,我的上下文类的OnModelCreating:
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);
}
我正在解析一个JSON文件,以生成带有其阶段和依存关系的研究列表。
JSON文件的片段
{
"Studies": [
{
"Name": "Concentrated",
"DependsOn": "",
"Stages": [
{
"Name": "IsConcentratedDone",
"Percentage": 25,
"Duration": 1
},
{
"Name": "WasDescribed",
"Percentage": 25,
"Duration": 1
},
{
"Name": "HasPhotos",
"Percentage": 25,
"Duration": 1
},
{
"Name": "ReportFinished",
"Percentage": 25,
"Duration": 1
}
]
},
{
"Name": "AFT",
"DependsOn": "Concentrated",
"Stages": [
{
"Name": "IsMountDone",
"Percentage": 25,
"Duration": 1
},
{
"Name": "SendedToIrradiation",
"Percentage": 25,
"Duration": 1
},
{
"Name": "WasRecepted",
"Percentage": 25,
"Duration": 1
},
{
"Name": "WasMeasured",
"Percentage": 25,
"Duration": 1
}
]
}
]
}
然后,我将此研究添加到DBContext类中适当的DBSet中,并且当我尝试保存更改时会抛出一个异常:
SqlException:INSERT语句与FOREIGN KEY SAME TABLE约束“ FK_AvailableStages_AvailableStages_DependsOnId”发生冲突。 数据库“ LateAndesSamples”的表“ dbo.AvailableStages”的列“ 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支持的唯一策略是逐层表,AKA单表继承。 这意味着对于像BusinessObject
这样的看似全局基类,您将最终得到一个巨大的表,并将所有其他类型塞入其中。 换句话说,一团糟。
通过使其抽象,派生类型将继承行为,但它们仍将各自获得自己的表。
我解决了!
解析JSON文件后,我正在调用以下方法:
//availables is a list of availiables studies generated after parsing json file
dbContext.AvailableStudies.AddRange(availables);
dbContext.SaveChanges();
但是当我详细查看时,没有依赖关系的阶段在DependsOnId属性上包含空字符串,而不是null。 将空字符串替换为null后,它可以正常工作!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.