EF Core - 具有相同依赖实体类型的附加导航 属性 的一对多关系
EF Core - One to many relationship with additional navigation property of same dependent entity type
我在 EF Core 中配置关系时遇到问题。我遇到了以下异常 -
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other
FOREIGN KEY constraints
我已经为这个 post 削减了实体,但是这两个实体都有自己的 table。
public class ApplicationSetupTest
{
public Guid Id { get; set; }
public Guid SchemeId { get; set; }
public string Description { get; set; }
public Guid LatestVersionId { get; set; }
public ApplicationSetupVersionTest LatestVersion { get; set; }
public ICollection<ApplicationSetupVersionTest> VersionHistory { get; set; }
}
public class ApplicationSetupVersionTest
{
public Guid Id { get; set; }
public Guid SetupId { get; set; }
public string Data { get; set; }
public string AuditComment { get; set; }
public Guid PreviousVersionId { get; set; }
}
ApplicationSetupTest
class 有效地定义了带有 LatestVersionId
的静态数据,它是导航键 属性 LatestVersion
.
ApplicationSetupVersionTest
class 是 versioned/audited 数据。这些中的每一个都有一个 SetupId
到 link 它回到 ApplicationSetupTest
是指。
我添加 VersionHistory
属性 纯粹是为了这个 post 以证明每个 ApplicationSetupTest
上可以有多个 ApplicationSetupVersionTest
。我没有在 ApplicationSetupVersionTest
上添加 ApplicationSetupTest
,因为这不是我期望需要的东西。
我的 ApplicationSetupTest
配置如下:
public class ApplicationSetupEntityConfiguration : IEntityTypeConfiguration<ApplicationSetupTest>
{
public void Configure(EntityTypeBuilder<ApplicationSetupTest> builder)
{
builder.Property(t => t.SchemeId).IsRequired();
builder.Property(t => t.Description).IsRequired();
builder.Property(t => t.LatestVersionId).IsRequired();
builder.HasMany(t => t.VersionHistory)
.WithOne()
.HasForeignKey(t => t.SetupId)
.IsRequired();
builder.HasOne(t => t.LatestVersion)
.WithOne()
.HasForeignKey<ApplicationSetupTest>(t => t.LatestVersionId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
builder.HasOne<Scheme>()
.WithMany()
.HasForeignKey(t => t.SchemeId)
.IsRequired();
}
}
VersionHistory
上的 HasMany
-> WithOne
定义了当我删除设置时,我应该删除所有版本实体。
因此我假设第二个配置是要更改的区域。 OnDelete(NoAction)
是在 Google 搜索之后添加的,我还尝试删除 IsRequired()
以及使 LatestVersionId
可为空。
我希望配置第二个关系,以便 LatestVersion
属性 可以包含在查询中。
关于如何配置这种关系有什么想法吗?还是我在做一些你不推荐的事情?
(为简单起见,我将模型称为 Setup
和 Version
)。
有了你的一对多配置 -
builder.HasMany(t => t.VersionHistory)
.WithOne()
.HasForeignKey(t => t.SetupId)
.IsRequired();
你声明了Setup
为主端,Version
为从属端,是正确的。
但是你在Setup
中有一个LatestVersionId
外键,引用Version
,一对一关系的配置-
builder.HasOne(t => t.LatestVersion)
.WithOne()
.HasForeignKey<ApplicationSetupTest>(t => t.LatestVersionId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
正在尝试将 Setup
配置为从属端,将 Version
配置为主体端。我相信你能看出其中的矛盾。
使用以下简化模型 -
public class Setup
{
public Guid Id { get; set; }
public string Description { get; set; }
public Version LatestVersion { get; set; }
public ICollection<Version> VersionHistory { get; set; }
}
public class Version
{
public Guid Id { get; set; }
public string Data { get; set; }
// not nullable - every Version must belong to a Setup
public Guid SetupIdHistory { get; set; }
// nullable - not every Version is a latest version
public Guid? SetupIdLatest { get; set; }
}
您可以正确配置它们以将您的关系表示为 -
public void Configure(EntityTypeBuilder<Setup> builder)
{
builder.HasMany(p => p.VersionHistory)
.WithOne()
.HasForeignKey(p => p.SetupIdHistory)
.OnDelete(DeleteBehavior.Cascade) // not required, cascading is default
.IsRequired();
builder.HasOne(p => p.LatestVersion)
.WithOne()
.HasForeignKey<Version>(p => p.SetupIdLatest)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired(false);
}
如果您选择不为一对多关系设置外键,EF 将为您创建一个可为空的外键,并在模型级别使用影子管理关系 属性。但是对于一对一的关系,你必须定义一个外键。
public class Version
{
public Guid Id { get; set; }
public string Data { get; set; }
// nullable - not every Version is a latest version
public Guid? SetupId { get; set; }
}
public void Configure(EntityTypeBuilder<Setup> builder)
{
builder.HasMany(p => p.VersionHistory)
.WithOne()
.OnDelete(DeleteBehavior.Cascade)
.IsRequired(); // this will have no effect, the FK will be nullable
builder.HasOne(p => p.LatestVersion)
.WithOne()
.HasForeignKey<Model.Version>(p => p.SetupId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired(false);
}
我在 EF Core 中配置关系时遇到问题。我遇到了以下异常 -
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints
我已经为这个 post 削减了实体,但是这两个实体都有自己的 table。
public class ApplicationSetupTest
{
public Guid Id { get; set; }
public Guid SchemeId { get; set; }
public string Description { get; set; }
public Guid LatestVersionId { get; set; }
public ApplicationSetupVersionTest LatestVersion { get; set; }
public ICollection<ApplicationSetupVersionTest> VersionHistory { get; set; }
}
public class ApplicationSetupVersionTest
{
public Guid Id { get; set; }
public Guid SetupId { get; set; }
public string Data { get; set; }
public string AuditComment { get; set; }
public Guid PreviousVersionId { get; set; }
}
ApplicationSetupTest
class 有效地定义了带有 LatestVersionId
的静态数据,它是导航键 属性 LatestVersion
.
ApplicationSetupVersionTest
class 是 versioned/audited 数据。这些中的每一个都有一个 SetupId
到 link 它回到 ApplicationSetupTest
是指。
我添加 VersionHistory
属性 纯粹是为了这个 post 以证明每个 ApplicationSetupTest
上可以有多个 ApplicationSetupVersionTest
。我没有在 ApplicationSetupVersionTest
上添加 ApplicationSetupTest
,因为这不是我期望需要的东西。
我的 ApplicationSetupTest
配置如下:
public class ApplicationSetupEntityConfiguration : IEntityTypeConfiguration<ApplicationSetupTest>
{
public void Configure(EntityTypeBuilder<ApplicationSetupTest> builder)
{
builder.Property(t => t.SchemeId).IsRequired();
builder.Property(t => t.Description).IsRequired();
builder.Property(t => t.LatestVersionId).IsRequired();
builder.HasMany(t => t.VersionHistory)
.WithOne()
.HasForeignKey(t => t.SetupId)
.IsRequired();
builder.HasOne(t => t.LatestVersion)
.WithOne()
.HasForeignKey<ApplicationSetupTest>(t => t.LatestVersionId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
builder.HasOne<Scheme>()
.WithMany()
.HasForeignKey(t => t.SchemeId)
.IsRequired();
}
}
VersionHistory
上的 HasMany
-> WithOne
定义了当我删除设置时,我应该删除所有版本实体。
因此我假设第二个配置是要更改的区域。 OnDelete(NoAction)
是在 Google 搜索之后添加的,我还尝试删除 IsRequired()
以及使 LatestVersionId
可为空。
我希望配置第二个关系,以便 LatestVersion
属性 可以包含在查询中。
关于如何配置这种关系有什么想法吗?还是我在做一些你不推荐的事情?
(为简单起见,我将模型称为 Setup
和 Version
)。
有了你的一对多配置 -
builder.HasMany(t => t.VersionHistory)
.WithOne()
.HasForeignKey(t => t.SetupId)
.IsRequired();
你声明了Setup
为主端,Version
为从属端,是正确的。
但是你在Setup
中有一个LatestVersionId
外键,引用Version
,一对一关系的配置-
builder.HasOne(t => t.LatestVersion)
.WithOne()
.HasForeignKey<ApplicationSetupTest>(t => t.LatestVersionId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
正在尝试将 Setup
配置为从属端,将 Version
配置为主体端。我相信你能看出其中的矛盾。
使用以下简化模型 -
public class Setup
{
public Guid Id { get; set; }
public string Description { get; set; }
public Version LatestVersion { get; set; }
public ICollection<Version> VersionHistory { get; set; }
}
public class Version
{
public Guid Id { get; set; }
public string Data { get; set; }
// not nullable - every Version must belong to a Setup
public Guid SetupIdHistory { get; set; }
// nullable - not every Version is a latest version
public Guid? SetupIdLatest { get; set; }
}
您可以正确配置它们以将您的关系表示为 -
public void Configure(EntityTypeBuilder<Setup> builder)
{
builder.HasMany(p => p.VersionHistory)
.WithOne()
.HasForeignKey(p => p.SetupIdHistory)
.OnDelete(DeleteBehavior.Cascade) // not required, cascading is default
.IsRequired();
builder.HasOne(p => p.LatestVersion)
.WithOne()
.HasForeignKey<Version>(p => p.SetupIdLatest)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired(false);
}
如果您选择不为一对多关系设置外键,EF 将为您创建一个可为空的外键,并在模型级别使用影子管理关系 属性。但是对于一对一的关系,你必须定义一个外键。
public class Version
{
public Guid Id { get; set; }
public string Data { get; set; }
// nullable - not every Version is a latest version
public Guid? SetupId { get; set; }
}
public void Configure(EntityTypeBuilder<Setup> builder)
{
builder.HasMany(p => p.VersionHistory)
.WithOne()
.OnDelete(DeleteBehavior.Cascade)
.IsRequired(); // this will have no effect, the FK will be nullable
builder.HasOne(p => p.LatestVersion)
.WithOne()
.HasForeignKey<Model.Version>(p => p.SetupId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired(false);
}