英文:
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<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);
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?
答案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; }
}
结果:
英文:
> 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("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; }
}
result:
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论