Tom*_*ski 4 c# entity-framework-core .net-core
我有实体框架核心,它执行我不想要的额外删除.
模型定义:我有两个实体Template和TemplateVersion.A TemplateVersion只是模板的下一个版本,所以TemplateVersion有一个Template(N:1关系)
public class Template
{
public int Id { get; set; }
}
public class TemplateVersion
{
public int Id { get; set; }
public Template Template { get;set; }
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都清楚是一种有益的工作.
但是:我想获得关于Template级别的信息,这是当前版本的TemplateVersion,所以我的Template定义现在看起来像(TemplateVersion和以前一样)
public class Template
{
public int Id { get; set; }
public TemplateVersion CurrentVersion { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
所以我想有是N的情况下TemplateVersion,以点1的情况下Template却在同一时间Template指向1 TemplateVersion
在这里,魔术开始了:当我添加一个Template,TemplateVersion一切都运转良好.
Template ---- TemplateVersionPrevious.Template == Template
Run Code Online (Sandbox Code Playgroud)
但是,当我添加另一个TemplateVersion指向同一个Template(和更新Template的CurrentVersion)的实例时,突然第一个实例将TemplateVersion其Template字段置为无效.
Template ---- TemplateVersionPrevious.Template == null
---- TemplateVersionCurrent.Template == Template
Run Code Online (Sandbox Code Playgroud)
我相信这是因为实体框架认为我有一个经典的1:1关系,只有一个实例TemplateVersion可以Template与它有关系- 这是因为CurrentTemplate字段.
我如何告诉实体框架它不应该清除我的TemplateVersion关系?
附加信息:一旦我定义我的TemplateVersion实体如下
public class TemplateVersion
{
public int Id { get; set; }
[ForeignKey(nameof(TemplateId))]
public Template Template { get;set; }
public int TemplateId {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
它变得更有趣:之前的实例TemplateVersion刚被删除!
Template ---- TemplateVersionCurrent.Template == Template
Run Code Online (Sandbox Code Playgroud)
EF默认约定不适用于2个实体之间的多个关系.并且数据注释不能很好地与一对一关系或单向关联(在一端没有导航属性的关系).
您需要使用流畅的API显式配置所需的关系.由于流利的API有不同的重载有/没有导航属性,并用它来纠正超载是很重要的,我们说你的模型是完全一样(正好我指的是导航和影响的关系,明确FK属性,其他属性都无关紧要):
public class Template
{
public int Id { get; set; }
public TemplateVersion CurrentVersion { get; set; }
}
public class TemplateVersion
{
public int Id { get; set; }
public Template Template { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所需两种关系的流畅配置如下:
modelBuilder.Entity<Template>()
.HasMany<TemplateVersion>()
.WithOne(e => e.Template)
.IsRequired();
modelBuilder.Entity<Template>()
.HasOne(e => e.CurrentVersion)
.WithOne()
.HasForeignKey<Template>("TemplateVersionId")
.IsRequired(false);
Run Code Online (Sandbox Code Playgroud)
请注意,您已定义了循环关系,因此其中一个应该是可选的.我选择Template..TemplateVersionId对我来说是合乎逻辑的选择.
还要注意的是一个一对一的关系,校长和相关两端不能唯一地确定HasOne/ WithOne,所以你需要使用HasForeignKey和HasPrinciplaKey 泛型类型参数指定(相反,一个一对多的关系,有没有这样的问题,因为一方始终是委托人而另一方是依赖方.
有关详细信息,请参阅关系.
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |