在 Entity Framework 上具有彼此键的两个表

Two tables that have keys to each other on Entity Framework

我有以下 类:

public class Condition 
{
    public int Id {get;set; }
    public Condition ParentCondition {get;set;}
    public Action ParentAction {get;set;}
    public string Whatever {get;set;}
}

public class Action 
{
    public int Id {get;set; }
    public Condition ParentCondition {get;set;}
    public Action ParentAction {get;set;}
    public string Whatever {get;set;}
}

因此,条件和操作都可以有一个条件或一个操作作为父项(或者 none 如果两者都为空)

我试图将其放入 SQL 数据库但不知何故丢失了。所以我想要实现的是(伪代码)

TABLE Condition:

int ConditionParent
int ActionParent

Table Action:

int ConditionParent
int ActoinParent

我试过使用 fluent api:

  modelBuilder.Entity<Condition>()
                .ToTable("Condition")
                .HasOptional(c => c.ParentAction)
                .WithRequired(a => a.ParentCondition);

但是当我这样做时,Action table 看起来不错,但是条件的迁移代码根本没有用于操作父级的列。

需要更改什么?

Conditions table 是否有一列用于其父操作!它是主键,同时也是 Action 的外键。

查看 table 的(基本)创建代码:

CREATE TABLE [dbo].[Actions](
    [Id] [int] NOT NULL,
    [ParentAction_Id] [int] NULL,
 CONSTRAINT [PK_dbo.Actions] PRIMARY KEY CLUSTERED ([Id]))

ALTER TABLE [dbo].[Actions] ADD CONSTRAINT [FK_dbo.Actions_dbo.Actions_ParentAction_Id]
    FOREIGN KEY([ParentAction_Id]) REFERENCES [dbo].[Actions] ([Id])

-- Here: primary key Id is foreign key to Condition
ALTER TABLE [dbo].[Actions] ADD CONSTRAINT [FK_dbo.Actions_dbo.Conditions_Id]
    FOREIGN KEY([Id]) REFERENCES [dbo].[Conditions] ([Id])

CREATE TABLE [dbo].[Conditions](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ParentCondition_Id] [int] NULL,
 CONSTRAINT [PK_dbo.Conditions] PRIMARY KEY CLUSTERED ([Id])
)

ALTER TABLE [dbo].[Conditions] ADD CONSTRAINT [FK_dbo.Conditions_dbo.Conditions_ParentCondition_Id]
    FOREIGN KEY([ParentCondition_Id]) REFERENCES [dbo].[Conditions] ([Id])

这是因为Action-Condition是一个1:1协会。 EF 始终通过此 PK/FK 构造实现所需的 1:1 关联。这是有道理的:如果没有所需的 Condition 父级,Action 就不可能存在。最好的保证方法是 Action 到 "borrow" Condition 的 PK 值。

我通过显式添加 ID 解决了这个问题:

public class Condition 
{
    public int Id {get;set; }
    public int? ParentConditionId {get;set;}
    public virtual Condition ParentCondition {get;set;}
    public int? ParentActionId {get;set; }
    public virtual Action ParentAction {get;set;}
    public string Whatever {get;set;}
}

public class Action 
{
    public int Id {get;set; }
    public int ParentConditionId {get;set;}
    public virtual Condition ParentCondition {get;set;}
    public int? ParentActionId {get;set;}
    public virtual Action ParentAction {get;set;}
    public string Whatever {get;set;}
}