gpt4 book ai didi

c# - Entityframework 是否在创建时自动分配导航属性

转载 作者:太空狗 更新时间:2023-10-29 21:44:19 26 4
gpt4 key购买 nike

当我运行下面提到的代码时,EF 会使用正确的 PersonId 保存 PersonAddress。我没有PersonAddress 实体添加到 Person 实体,尽管我没有这样做,但我的数据库中的记录已正确链接。

我的问题是:EF 是否会自动 添加相关实体,即使我没有指定它所属的实体?如果是这样,这不会导致不需要的实体关系吗?

更新

似乎由于以下原因正确保存了实体:

  1. 创建实体 Person 时,PersonId 字段为 0
  2. PersonAddress.PersonId 在创建时也是 0。

通过在创建时手动将 Person.PersonId 设置为任意值,然后将 PersonAddress.PersonId 设置为与 Person.PersonId 相同的值 EF 正确保存数据,因为它们共享相同的 PersonId

因此从技术上讲,EF 不会自动添加相关实体,它们是相关的,因为它们共享相同的 PersonId

引用以下代码:

        using (var context = new Models.TestEntities())
{
var person = context.People.Create();

var postalAddress = context.PersonAddresses.Create();
postalAddress.AddressLine1 = "PostalAddressLine1";

var residentialAddress = context.PersonAddresses.Create();
residentialAddress.AddressLine1 = "ResidentialAddressLine1";

context.People.Add(person);
context.PersonAddresses.Add(postalAddress);
context.PersonAddresses.Add(residentialAddress);

context.SaveChanges();
}

当我在代码中添加额外的 Person 时,出现以下错误: enter image description here
代码:

        using (var context = new Models.TestEntities())
{
var person = context.People.Create();
var person2 = context.People.Create();

var postalAddress = context.PersonAddresses.Create();
postalAddress.AddressLine1 = "PostalAddressLine1";

var residentialAddress = context.PersonAddresses.Create();
residentialAddress.AddressLine1 = "ResidentialAddressLine1";

context.People.Add(person);
context.People.Add(person2);

context.PersonAddresses.Add(postalAddress);
context.PersonAddresses.Add(residentialAddress);

context.SaveChanges();
}

由于指定的错误,Entityframework 现在无法确定 PersonAddress 实体属于谁。

我可以通过如下修改代码来解决这个问题:

        using (var context = new Models.TestEntities())
{
var person = context.People.Create();
var person2 = context.People.Create();

var postalAddress = context.PersonAddresses.Create();
postalAddress.AddressLine1 = "PostalAddressLine1";

var residentialAddress = context.PersonAddresses.Create();
residentialAddress.AddressLine1 = "ResidentialAddressLine1";

context.People.Add(person);
context.People.Add(person2);

person.PersonAddresses.Add(residentialAddress);
person.PersonAddresses.Add(postalAddress);

context.SaveChanges();
}

请参阅下面的 EDMX:

enter image description here

请参阅用于创建两个表的 SQL 脚本:

CREATE TABLE Person
(
PersonId INT IDENTITY(1,1) NOT NULL CONSTRAINT [PK_Person] PRIMARY KEY,
FirstName VARCHAR(250)
)

CREATE TABLE PersonAddress
(
PersonAddressId INT IDENTITY(1,1) NOT NULL CONSTRAINT [PK_PersonAddress] PRIMARY KEY,
PersonId INT NOT NULL,
AddressLine1 VARCHAR(250)
)

ALTER TABLE PersonAddress
ADD CONSTRAINT [FK_PersonAddress_Person] FOREIGN KEY(PersonId)
REFERENCES [Person](PersonId)

请参阅下面的 Id 列屏幕截图: enter image description here enter image description here enter image description here

请查看下面的 SQL Server Profiler 跟踪:

人物:
enter image description here

个人地址:
enter image description here

个人地址:
enter image description here

请在SQL中查看插入的记录:

人物:
enter image description here

个人地址:
enter image description here

谢谢。

最佳答案

这是发生了什么:

var person = context.People.Create();

Person 被创建时 PersonId = 0。

var postalAddress           = context.PersonAddresses.Create();
postalAddress.AddressLine1 = "PostalAddressLine1";
var residentialAddress = context.PersonAddresses.Create();
residentialAddress.AddressLine1 = "ResidentialAddressLine1";

地址已创建,同时 PersonId = 0。

context.People.Add(person);
context.PersonAddresses.Add(postalAddress);
context.PersonAddresses.Add(residentialAddress);

EF 已执行关系修复,即它已匹配地址的 PersonIdPersonPersonId(全为0)并在它们之间建立关联。

context.SaveChanges();

数据库已将标识值分配给 Person.PersonId。 EF 将其从数据库读回实体。

在第二个片段中,有两个 PersonPersonId = 0,因此现在 EF 不知道将地址与哪个人相关联。

做什么

显然,这是意外行为。最好的办法是明确关联实体,如果它们打算相关,就像在您的第三个代码段中一样。

一旦您了解了这些自动关联,您可能希望通过为 Person.PersonId 分配一个不同于 0 的默认值来阻止它们,例如-1。现在 EF 不会将此 ID 与具有整数默认值 0 的任何其他外部值相匹配。

关于c# - Entityframework 是否在创建时自动分配导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29511866/

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