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

Tja*_*alt 6 c# entity-framework

当我运行下面提到的代码时,EF保存PersonAddress正确PersonId.我没有PersonAddress实体添加到Person实体,即使我没有这样做,我的数据库中的记录也正确链接.

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

更新

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

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

通过Person.PersonId在创建时手动设置为任意值,然后设置PersonAddress.PersonId为相同的Person.PersonIdEF 值,可以在共享数据时正确保存数据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();
        }
Run Code Online (Sandbox Code Playgroud)

当我Person在代码中添加额外内容时,我收到以下错误: 在此输入图像描述
码:

        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();
        }
Run Code Online (Sandbox Code Playgroud)

由于指定的错误,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();
        }
Run Code Online (Sandbox Code Playgroud)

请参阅下面的EDMX:

在此输入图像描述

请参阅用于创建两个表的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)
Run Code Online (Sandbox Code Playgroud)

请参阅以下Id列截图: 在此输入图像描述 在此输入图像描述 在此输入图像描述

请参阅下面的SQL Server Profiler跟踪:

Person:
在此输入图像描述

PersonAddress:
在此输入图像描述

PersonAddress:
在此输入图像描述

请参阅SQL中插入的记录:

Person:
在此输入图像描述

PersonAddress:
在此输入图像描述

谢谢.

Ger*_*old 4

发生的情况如下:

var person = context.People.Create();
Run Code Online (Sandbox Code Playgroud)

APerson被创建为PersonId= 0。

var postalAddress           = context.PersonAddresses.Create();
postalAddress.AddressLine1  = "PostalAddressLine1";
var residentialAddress          = context.PersonAddresses.Create();
residentialAddress.AddressLine1 = "ResidentialAddressLine1";
Run Code Online (Sandbox Code Playgroud)

地址被创建,也有PersonId= 0。

context.People.Add(person);
context.PersonAddresses.Add(postalAddress);
context.PersonAddresses.Add(residentialAddress);
Run Code Online (Sandbox Code Playgroud)

EF 已经执行了关系修复,即它已经匹配了地址PersonId和 的PersonPersonId全0)并在它们之间建立了关联。

context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

数据库已为 分配了一个标识值Person.PersonId。EF 将其从数据库读回到实体中。

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

该怎么办

显然,这是意想不到的行为。最好的办法是显式关联实体(如果它们想要相关),如您的第三个片段中所示。

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