繁体   English   中英

如何创建一对一关系,双方关系都是可选的

[英]How to create a one-to-one relationship where the relationship on both sides is optional

是否可以在两个实体之间创建关系,其中每个实体都具有到另一个的外键,并且外键字段也是可选的? 我尝试根据以下代码创建表:

public class Museum
{
    public int MuseumId { get; set; }
    public string Name { get; set; }

    [ForeignKey("Curator")]
    public int? CuratorId { get; set; }
    public virtual Curator Curator { get; set; }
}

public class Curator
{
    public int CuratorId { get; set; }
    public string Name { get; set; }

    [ForeignKey("Museum")]
    public int? MuseumId { get; set; }
    public virtual Museum Museum { get; set; }
}

但是我收到以下错误:

Curator_Museum_Target::多重性在关系“ Curator_Museum”中的角色“ Curator_Museum_Target”中无效。 因为从属角色属性不是关键属性,所以从属角色多重性的上限必须为'*'。

有什么办法可以解决这个问题?

您无法在数据库中做到这一点。 FK必须在关系的另一端引用PK。 并且PK不能是可选的。 例如,要在表AB之间实现的关系将具有以下条件:

  • 如果A.Id是与B.Id相关的FK,则B.Id必须是PK,因此不是可选的
  • 反之亦然,如果B.Id是与A.Id相关的FK,则A.Id必须是PK,因此不是可选的

因此,这不是EF的问题,而是模型的问题。

为了模拟这一点,您可以使用一个桥接表,例如“ pseducode”:

[Table: ABBridge]
AId not null
BId not null

因此,如果存在从AB的依赖关系,反之亦然,则只需向该表添加一个条目。 没有这种关系,此表中没有字段。 AIdBId都应该是桥接表的PK。

这将是多对多关系。 如果您使用的是现代版本的EF(6.1或更高版本),则可以通过将AIdBId都使用带有IsUniqueIndex属性来使AIdBId唯一来进行一对一转换

[Index("AIdUniqueIndex", IsUnique = true)]
public int AId { get; set; }
[Index("BIdUniqueIndex", IsUnique = true)]
public int AId { get; set; }

如果使用的是较旧的版本,则应使用业务逻辑来确保这一点。

您可以使用ModelBuilder的流畅的API进行配置。

对于可选的1:1关系,代码为:

ModelBuilder.Entity<Museum>().HasOptional(x => x.Curator).WithOptionalPrincipal(x => x.Museum).WillCascadeOnDelete(true);

如JotaBe所述,当将此配置映射到数据库时,EF不会在两个表中都创建外键列。 而是仅为HasOptional()子句中定义的边创建FK列。 主/唯一键基表将在配置为WithOptionalPrincipal()的那一侧。

对于示例代码,数据库的FK约束将在Curator表中创建为Curator.Museum_Id-> Museum.Id,而Museum为主/唯一键基表。

还要注意,上面给出的代码将级联delte配置为“如果博物馆被删除,则删除策展人”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM