Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

huangapple go评论66阅读模式
英文:

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

问题

我试着帮你翻译一下:

我的用例基本上与教程中看到的一样:我有一个类 Slachtoffer 和另一个类 Schadeberekening。每个 Schadeberekening 必须有一个 Slachtoffer,而一个 Slachtoffer 可以有一个 Schadeberekening

我正在尝试使用代码优先方式设置数据库,如下所示:

public class Slachtoffer
{
    public int Id { get; set; }

    public int? SchadeberekeningId{ get; set; }
    public Schadeberekening? Schadeberekening { get; set; }
}

public class Schadeberekening
{
    public int Id { get; set; }

    public int SlachtofferId { get; set; }
    public Slachtoffer Slachtoffer { get; set; }
}

modelBuilder.Entity<Slachtoffer>()
             .HasOne(s => s.Schadeberekening)
             .WithOne(ad => ad.Slachtoffer)
             .HasForeignKey<Schadeberekening>(ad => ad.SlachtofferId);

modelBuilder.Entity<Schadeberekening>()
             .HasOne<Slachtoffer>(a => a.Slachtoffer)
             .WithOne(sa => sa.Schadeberekening)
             .HasForeignKey<Slachtoffer>(sa => sa.SchadeberekeningId);

然而,当我查看创建的表时,只有在 Slachtoffer 表中,来自 Schadeberekening 的主键被视为外键。在 Schadeberekening 表中,它只是一个 "int"。

我该如何修复这个问题?

英文:

My use case is pretty much identical to what I see in the tutorials: I have a class Slachtoffer and another class Schadeberekening. Each Schadeberekening must have a Slachtoffer, and a Slachtoffer can have a Schadeberekening.

I am trying to set up the database using code-first like this:

public class Slachtoffer
{
    public int Id { get; set; }

    public int? SchadeberekeningId{ get; set; }
    public Schadeberekening? Schadeberekening { get; set; }
}

public class Schadeberekening
{
    public int Id { get; set; }

    public int SlachtofferId { get; set; }
    public Slachtoffer Slachtoffer { get; set; }
}

modelBuilder.Entity&lt;Slachtoffer&gt;()
             .HasOne(s =&gt; s.Schadeberekening)
             .WithOne(ad =&gt; ad.Slachtoffer)
             .HasForeignKey&lt;Schadeberekening&gt;(ad =&gt; ad.SlachtofferId);

modelBuilder.Entity&lt;Schadeberekening&gt;()
             .HasOne&lt;Slachtoffer&gt;(a =&gt; a.Slachtoffer)
             .WithOne(sa =&gt; sa.Schadeberekening)
             .HasForeignKey&lt;Slachtoffer&gt;(sa =&gt; sa.SchadeberekeningId);

Yet when I look at the created tables, only in the Slachtoffer table, the PK from the Schadeberekening is considered as foreign key. In the Schadeberekening table, it is just an "int".

How can I fix this?

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

答案1

得分: 1

> 在 Schadeberekening 中,它只是一个 "int"。我该怎么解决这个问题?

我有一个建议,就像下面这样,移除 OnModelCreating 中的代码,并修改你的代码:

受害者:

public class Slachtoffer
{
    public int Id { get; set; }

    [ForeignKey("Schadeberekening")]
    public int? SchadeberekeningId { get; set; }
    public virtual Schadeberekening? Schadeberekening { get; set; }
}

Schadeberekening:

public class Schadeberekening
{
    public int Id { get; set; }

    [ForeignKey("Slachtoffer")]
    public int SlachtofferId { get; set; }

    public virtual Slachtoffer Slachtoffer { get; set; }
}

结果:

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

英文:

> In the Schadeberekening, it is just an "int". How can I fix this?

I have a suggestion like below, remove the code in OnModelCreating, and modify your code like:

Slachtoffer:

public class Slachtoffer
    {
        public int Id { get; set; }

        [ForeignKey(&quot;Schadeberekening&quot;)]
        public int? SchadeberekeningId { get; set; }
        public virtual Schadeberekening? Schadeberekening { get; set; }
    }

Schadeberekening:

public class Schadeberekening
    {
        public int Id { get; set; }

        [ForeignKey(&quot;Slachtoffer&quot;)]
        public int SlachtofferId { get; set; }

        public virtual Slachtoffer Slachtoffer { get; set; }
    }

result:

Optional one-to-one relationship in entitiy framework does not result in the right Foreign-Primary key in my sql database

答案2

得分: 1

One to one relationships in EF can be configured in two ways. The default, and best enforceable way is to join the two tables on their PKs. You would choose one entity as the Root for the relationship, and the related table would share that Id serving as both the PK and the FK back to the root. The relationship can still be nullable (1-to-0-or-1):

在EF中,一对一关系可以以两种方式配置。默认且最可强制执行的方式是通过它们的主键将两个表连接起来。您会选择一个实体作为关系的根,相关表将共享该Id,既作为主键又作为返回到根的外键。关系仍然可以为可空(1对0或1):

public class Slachtoffer
{
public int Id { get; set; }

public Schadeberekening? Schadeberekening { get; set; }

}

public class Schadeberekening
{
[Key, ForeignKey(nameof(Slachtoffer))]
public int Id { get; set; }

public virtual Slachtoffer Slachtoffer { get; set; }

}

Note that there are no FK fields in either table, the Schadeberekening associated to a Slachtoffer will share the same ID. If you are explicitly managing the key setup, the Id in the Slachtoffer would be treated as an Identity, while in the Schadeberekening it should not be, as Slachtoffer will be responsible for controlling that ID.

请注意,两个表中都没有FK字段,与Slachtoffer关联的Schadeberekening将共享相同的ID。如果您明确管理主键设置,Slachtoffer中的Id将被视为标识,而在Schadeberekening中则不应该,因为Slachtoffer将负责控制该ID。

The second way to configure a 1-to-1 is using an explicit FK. This would only exist on one table or the other, not both. So for example:

配置1对1的第二种方法是使用显式的FK。这只会存在于其中一个表格,而不是两者都有。例如:

public class Slachtoffer
{
public int Id { get; set; }

public int? Schadeberekening { get; set; }
public Schadeberekening? Schadeberekening { get; set; }

}

public class Schadeberekening
{
public int Id { get; set; }

public virtual Slachtoffer Slachtoffer { get; set; }

}

In this case you would need to tell EF about the 1-to-1 relationship and that it should locate the FK in the Slachtoffer table using the prescribed FK column. (This ideally should be set up as a Shadow Property in the entity)

在这种情况下,您需要告诉EF关于1对1关系以及它应该使用指定的FK列在Slachtoffer表中定位FK。(理想情况下,这应该设置为实体中的Shadow属性)

If configured as a 1-to-1 relationship, EF will do its best to respect that constraint, but at the database level this is a many-to-one relationship unless you add a unique constraint on Slacktoffer.SchadeberekeningId. (Code-first may do this as part of the HasOne().WithOne()) You don't have another FK in the secondary table to go back to the parent since that creates the potential to have broken and invalid relationships. For instance if I have A referencing B with a reference back to A, If I change A's reference to C, it is possible that B's reference back to A does not get removed, or C to A does not get created.

如果配置为1对1关系,EF将尽力尊重该约束,但在数据库级别,这是一对多关系,除非您在Slacktoffer.SchadeberekeningId上添加唯一约束(Code-first可能会在“HasOne().WithOne()”的一部分执行此操作)。由于在次要表中没有另一个FK可返回到父表,因此可能会导致破损和无效的关系。例如,如果我有一个引用B的A,并有一个引用回A的B,如果我将A的引用更改为C,那么B对A的引用可能不会被删除,或者C对A的引用可能不会被创建。

A good breakdown of options for creating one-to-one relationships can be found here: https://learn.microsoft.com/en-us/ef/core/modeling/relationships/one-to-one

有关创建一对一关系的选项的良好详细信息可以在这里找到:https://learn.microsoft.com/en-us/ef/core/modeling/relationships/one-to-one

英文:

One to one relationships in EF can be configured in two ways. The default, and best enforceable way is to join the two tables on their PKs. You would choose one entity as the Root for the relationship, and the related table would share that Id serving as both the PK and the FK back to the root. The relationship can still be nullable (1-to-0-or-1):

public class Slachtoffer
{
    public int Id { get; set; }

    public Schadeberekening? Schadeberekening { get; set; }
}

public class Schadeberekening
{
    [Key, ForeignHey(nameof(Slachtoffer))]
    public int Id { get; set; }

    public virtual Slachtoffer Slachtoffer { get; set; }
}

Note that there are no FK fields in either table, the Schadeberekening associated to a Slachtoffer will share the same ID. If you are explicitly managing the key setup, the Id in the Slachtoffer would be treated as an Identity, while in the Schadeberekening it should not be, as Slachtoffer will be responsible for controlling that ID.

The second way to configure a 1-to-1 is using an explicit FK. This would only exist on one table or the other, not both. So for example:

public class Slachtoffer
{
    public int Id { get; set; }

    public int? Schadeberekening { get; set; }
    public Schadeberekening? Schadeberekening { get; set; }
}

public class Schadeberekening
{
    public int Id { get; set; }

    public virtual Slachtoffer Slachtoffer { get; set; }
}

In this case you would need to tell EF about the 1-to-1 relationship and that it should locate the FK in the Slachtoffer table using the prescribed FK column. (This ideally should be set up as a Shadow Property in the entity)

If configured as a 1-to-1 relationship, EF will do its best to respect that constraint, but at the database level this is a many-to-one relationship unless you add a unique constraint on Slacktoffer.SchadeberekeningId. (Code-first may do this as part of the HasOne().WithOne()) You don't have another FK in the secondary table to go back to the parent since that creates the potential to have broken and invalid relationships. For instance if I have A referencing B with a reference back to A, If I change A's reference to C, it is possible that B's reference back to A does not get removed, or C to A does not get created.

A good breakdown of options for creating one-to-one relationships can be found here: https://learn.microsoft.com/en-us/ef/core/modeling/relationships/one-to-one

huangapple
  • 本文由 发表于 2023年4月20日 08:49:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76059793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定