简体   繁体   English

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

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

Is it possible to create a relationship between two entities where each entity has a foreign key to the other and the foreign key fields also optional? 是否可以在两个实体之间创建关系,其中每个实体都具有到另一个的外键,并且外键字段也是可选的? I tried creating tables based on the following code: 我尝试根据以下代码创建表:

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; }
}

But I get the following error: 但是我收到以下错误:

Curator_Museum_Target: : Multiplicity is not valid in Role 'Curator_Museum_Target' in relationship 'Curator_Museum'. Curator_Museum_Target::多重性在关系“ Curator_Museum”中的角色“ Curator_Museum_Target”中无效。 Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. 因为从属角色属性不是关键属性,所以从属角色多重性的上限必须为'*'。

Is there any way to get around this? 有什么办法可以解决这个问题?

You can't do that in a database. 您无法在数据库中做到这一点。 A FK must refer to a PK on the other side of the relation. FK必须在关系的另一端引用PK。 And a PK cannot be optional. 并且PK不能是可选的。 For example, the relation that you want o implement between tables A and B would have these conditions: 例如,要在表AB之间实现的关系将具有以下条件:

  • if A.Id is an FK related to B.Id , B.Id must be a PK, and thus, not optional 如果A.Id是与B.Id相关的FK,则B.Id必须是PK,因此不是可选的
  • and viceversa, if B.Id is an FK related to A.Id , A.Id must be a PK, and thus, not optional 反之亦然,如果B.Id是与A.Id相关的FK,则A.Id必须是PK,因此不是可选的

So, this is not a problem of EF, but a problem of your model. 因此,这不是EF的问题,而是模型的问题。

To simulate this you can use a bridge table, like this "pseducode": 为了模拟这一点,您可以使用一个桥接表,例如“ pseducode”:

[Table: ABBridge]
AId not null
BId not null

So, if there is a dependency form A to B or viceversa, you simply have to add an entry to this table. 因此,如果存在从AB的依赖关系,反之亦然,则只需向该表添加一个条目。 It there is no such relation, there is no field in this table. 没有这种关系,此表中没有字段。 Both AId an BId should be the PK for the bridge table. AIdBId都应该是桥接表的PK。

This would be a many-to-many relation. 这将是多对多关系。 If you're using a modern version of EF (6.1 or later) you can convert it in a one-to-one by making both AId and BId unique by using the Index attribute with IsUnique in both of them. 如果您使用的是现代版本的EF(6.1或更高版本),则可以通过将AIdBId都使用带有IsUniqueIndex属性来使AIdBId唯一来进行一对一转换

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

If you are using an older version, you should ensure this using business logic. 如果使用的是较旧的版本,则应使用业务逻辑来确保这一点。

You can configure this by using the fluent API of the ModelBuilder. 您可以使用ModelBuilder的流畅的API进行配置。

For an optional 1:1 relationship the code is: 对于可选的1:1关系,代码为:

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

As JotaBe noted EF will not create a foreign key column in both tables when mapping this config to the database. 如JotaBe所述,当将此配置映射到数据库时,EF不会在两个表中都创建外键列。 Instead the FK column will only be created for the side defined in the HasOptional() clause. 而是仅为HasOptional()子句中定义的边创建FK列。 The primary/unique key base table will be the side configured as WithOptionalPrincipal(). 主/唯一键基表将在配置为WithOptionalPrincipal()的那一侧。

For the example code, the FK constraint on the DB would be created in the Curator table as Curator.Museum_Id -> Museum.Id, with Museum as the Primary/Unique key base table. 对于示例代码,数据库的FK约束将在Curator表中创建为Curator.Museum_Id-> Museum.Id,而Museum为主/唯一键基表。

Also note that the code given above configures cascade delte as "delete the curator if the museum gets deleted". 还要注意,上面给出的代码将级联delte配置为“如果博物馆被删除,则删除策展人”。

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

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