gpt4 book ai didi

entity-framework - Entity Framework : one to zero or one relationship with foreign key on principal

转载 作者:行者123 更新时间:2023-12-01 04:53:22 25 4
gpt4 key购买 nike

我有一个 1:0..1 的关系,我想使用 fluent API 与 EF 6 进行映射。该关系由一个主体组成,该主体可能有也可能没有依赖关系。受抚养人必须始终有一个委托(delegate)人。

在主体中,我需要访问依赖项的 ID。

我的代码如下所示:

public class Principal
{
public int Id {get; private set; }

public int? DependentId { get; private set; }
public virtual Dependent Dependent { get; private set; }
}

public class Dependent
{
public int Id { get; private set; }

public virtual Principal Principal { get; private set; }
}

我的映射如下所示:
    public class PrincipalMap : EntityTypeConfiguration<Principal>
{
public PrincipalMap()
{
ToTable("PRINCIPALS");

HasKey(x => x.Id);

Property(x => x.Id)
.HasColumnName("PRINCIPALID")
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(x => x.DependentId)
.HasColumnName("DEPENDENTID")
.IsOptional();
}
}

public class DependentMap : EntityTypeConfiguration<Dependent>
{
public DependentMap()
{
ToTable("DEPENDENTS");

HasKey(x => x.Id);

Property(x => x.Id)
.HasColumnName("DEPENDENTID")
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

HasRequired(x => x.Principal).WithOptional(x => x.Dependent).Map(x => x.MapKey("PRINCIPALID")).WillCascadeOnDelete();
}
}

这会导致以下迁移:
            CreateTable(
"dbo.PRINCIPALS",
c => new
{
PRINCIPALID = c.Int(nullable: false, identity: true),
DEPENDENTID = c.Int(),
})
.PrimaryKey(t => t.PRINCIPALID);

CreateTable(
"dbo.DEPENDENTS",
c => new
{
DEPENDENTID = c.Int(nullable: false, identity: true),
PRINCIPALID = c.Int(nullable: false),
})
.PrimaryKey(t => t.DEPENDENTID)
.ForeignKey("dbo.PRINCIPALS", t => t.PRINCIPALID, cascadeDelete: true)
.Index(t => t.PRINCIPALID);

如您所见,列 DEPENDENTID不是外键。当运行程序并将依赖对象关联到主体时, DependentId房产空置 ,即 EF 不承认它与依赖本身有关。

我究竟做错了什么?

最佳答案

在 DependentMap 中,您将字段 DEPENDENTID 声明为 DEPENDENT 表的主键,由数据库生成(身份),因此它永远不会是外键。您不能随意更改它(使其指向您选择的实体)。

此外,使用 EF(和 E/R),您不需要两列(每表一列)来建立 1-0..1 关系。您只能拥有一列(不可为空)。

在您的情况下,此模型应该可以工作:

public class Principal
{
public int Id { get; private set; }

public virtual Dependent Dependent { get; private set; }
}

public class Dependent
{
public int Id { get; private set; }

public virtual Principal Principal { get; private set; }
}

public class PrincipalMap : EntityTypeConfiguration<Principal>
{
public PrincipalMap()
{
ToTable("PRINCIPALS");

HasKey(x => x.Id);

Property(x => x.Id)
.HasColumnName("PRINCIPALID")
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}

public class DependentMap : EntityTypeConfiguration<Dependent>
{
public DependentMap()
{
ToTable("DEPENDENTS");

HasKey(x => x.Id);

Property(x => x.Id)
.HasColumnName("DEPENDENTID")
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

HasRequired(x => x.Principal).WithOptional(x => x.Dependent).Map(x => x.MapKey("PRINCIPALID")).WillCascadeOnDelete();
}
}

在这种情况下,表创建状态(由 EF 提供程序生成)应该类似于
ExecuteNonQuery==========
CREATE TABLE [DEPENDENTS] (
[DEPENDENTID] int not null identity(1,1)
, [PRINCIPALID] int not null
);
ALTER TABLE [DEPENDENTS] ADD CONSTRAINT [PK_DEPENDENTS_204c4d57] PRIMARY KEY ([DEPENDENTID])
ExecuteNonQuery==========
CREATE TABLE [PRINCIPALS] (
[PRINCIPALID] int not null identity(1,1)
);
ALTER TABLE [PRINCIPALS] ADD CONSTRAINT [PK_PRINCIPALS_204c4d57] PRIMARY KEY ([PRINCIPALID])
ExecuteNonQuery==========
CREATE INDEX [IX_PRINCIPALID] ON [DEPENDENTS] ([PRINCIPALID])
ExecuteNonQuery==========
ALTER TABLE [DEPENDENTS] ADD CONSTRAINT [FK_DEPENDENTS_PRINCIPALS_PRINCIPALID] FOREIGN KEY ([PRINCIPALID]) REFERENCES [PRINCIPALS] ([PRINCIPALID])

(我省略了级联删除,但也应该清楚)。

E/R 模型是正常形式的(并且是唯一适用于 EF 的)。
顺便说一句,如果您访问 Principal.Dependent属性 EF 将生成类似于 selected * from dependent where PRINCIPALID = <principal_id> 的查询主体实体的 ID 在哪里,所以它确实有效。

现在,关于您的要求,从 Principal 访问 Dependent.Id 的唯一方法是 dependentId = Principal.Dependent.Id (或者,更好的是 dependentId = Principal.Dependent == null ? null : Principal.Dependent.Id )。

遇到 怎么办真的很想要 PRINCIPAL 上引用 DEPENDENT 表的外键字段?
此模型不是正常形式,因此 EF 不会处理它(对于 DBMS,您也需要编写触发器来处理它)。
我的意思是,在 R-DBMS 中,没有一个约束可以指定如果列 DEPENDENT.PRINCIPALID 引用 PRINCIPAL,列 PRINCIPAL.DEPENDENTID 也应该引用原始 DEPENDENT。
在这种情况下,您需要做的是自己处理 PRINCIPAL.DEPENDENTID(即 Principal 实体必须具有您必须自己处理的 DEPENDENTID 属性,并且在导航期间不被 EF 使用)。

关于entity-framework - Entity Framework : one to zero or one relationship with foreign key on principal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39170619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com