如何在 EF 6 的 Fluent API 中映射 1 到 0 或 1 的关系
How do I map a 1 to 0 or 1 relationship in Fluent API in EF 6
已编辑
我有 2 个 tables,护士和人员。 Person 与 Nurse 具有 1 对 0 或 1 的关系。换句话说,我申请中的某些人也将是一名护士。我想在两个 table 中使用相同的主键。当我 运行 我的代码查询护士 table 时,我得到一个 "System.Data.Entity.Core.EntityCommandExecutionException",然后是内部异常:"SqlException: Invalid column name 'Person_Id'."
我的 Nurse 模型中没有 "Person_Id" 字段。生成的查询似乎已经添加了它。我一定是在我的模型定义中遗漏了一些东西,因为删除 "public virtual Person Person { get; set; }" 会使查询正确生成。 EF 似乎挂断了 PK 在 Person table 中是 Id,但在 Nurse table 中是 NurseId。
我在 Internet 上找到了多个向您展示如何使用 Fluent API 进行映射的地方,但没有一个与我的情况相符。因为我的应用程序中的大多数人都不是 Nurse,所以我不想在我的 Person 模型中引用 Nurse 模型,这带走了我一直在网上看到的解决方案:
//won't work because I am trying to no have a reference to Nurse in my Person model. So i.Nurse below doesn't exist
modelBuilder.Entity<Nurse>().HasRequired(i => i.Person).WithOptional(i => i.Nurse)
查询 EF 生成:
{SELECT
1 AS [C1],
[Extent1].[NurseId] AS [NurseId],
[Extent1].[CredentialId] AS [CredentialId],
[Extent1].[DisciplineId] AS [DisciplineId],
[Extent1].[UnitId] AS [UnitId],
[Extent1].[YearsOfService] AS [YearsOfService],
[Extent1].[Person_Id] AS [Person_Id]
FROM [dbo].[Nurse] AS [Extent1]}
以下是 table:
CREATE TABLE [dbo].[Person]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK__Person] PRIMARY KEY CLUSTERED ([Id] ASC)
)
CREATE TABLE [dbo].[Nurse]
(
[NurseId] BIGINT NOT NULL,
CONSTRAINT [PK_Nurse] PRIMARY KEY ([NurseId]),
CONSTRAINT [FK_Nurse_Person] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Person] ([Id])
)
和实体:
public class Person
{
[Key]
public long Id { get; set; }
}
public class Nurse
{
[Key]
public long NurseId { get; set; }
public long? CredentialId { get; set; }
public long? DisciplineId { get; set; }
public long? UnitId { get; set; }
public int? YearsOfService { get; set; }
[ForeignKey("PersonId")]
public virtual Person Person { get; set; }
[ForeignKey("CredentialId")]
public virtual Credential Credential { get; set; }
[ForeignKey("DisciplineId")]
public virtual Discipline Discipline { get; set; }
[ForeignKey("UnitId")]
public virtual Unit Unit { get; set; }
}
ApplicationDBContext:
public class ApplicationDBContext : DbContext
{
public ApplicationDBContext() : base("ApplicationDbContext")
{
}
public DbSet<Nurse> Nurses { get; set; }
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Nurse>().HasKey(n => n.NurseId);
}
}
是否可以这样做,或者我是否需要参考 Nurse in my Person table 并使用我在网上看到的内容?
我认为您的问题是您使用的 PersonId 在 Nurse 中具有主键。尝试给 Nurse 一个自己的 Id。每个 table 都有自己的 ID 是个好主意。 EF 存在 table 或没有唯一主键的视图的问题。
CREATE TABLE [dbo].[Person]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK__Person] PRIMARY KEY CLUSTERED ([Id] ASC)
)
CREATE TABLE [dbo].[Nurse]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
[PersonId] BIGINT unique NOT NULL,
CONSTRAINT [PK_Nurse] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Nurse_Person] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Person] ([Id])
)
对于那些偶然发现这一点的人。我找到了答案 here。我贴的流利的api很接近,应该是:
modelBuilder.Entity<Nurse>().HasRequired(n => n.Person).WithOptional();
已编辑
我有 2 个 tables,护士和人员。 Person 与 Nurse 具有 1 对 0 或 1 的关系。换句话说,我申请中的某些人也将是一名护士。我想在两个 table 中使用相同的主键。当我 运行 我的代码查询护士 table 时,我得到一个 "System.Data.Entity.Core.EntityCommandExecutionException",然后是内部异常:"SqlException: Invalid column name 'Person_Id'."
我的 Nurse 模型中没有 "Person_Id" 字段。生成的查询似乎已经添加了它。我一定是在我的模型定义中遗漏了一些东西,因为删除 "public virtual Person Person { get; set; }" 会使查询正确生成。 EF 似乎挂断了 PK 在 Person table 中是 Id,但在 Nurse table 中是 NurseId。
我在 Internet 上找到了多个向您展示如何使用 Fluent API 进行映射的地方,但没有一个与我的情况相符。因为我的应用程序中的大多数人都不是 Nurse,所以我不想在我的 Person 模型中引用 Nurse 模型,这带走了我一直在网上看到的解决方案:
//won't work because I am trying to no have a reference to Nurse in my Person model. So i.Nurse below doesn't exist
modelBuilder.Entity<Nurse>().HasRequired(i => i.Person).WithOptional(i => i.Nurse)
查询 EF 生成:
{SELECT
1 AS [C1],
[Extent1].[NurseId] AS [NurseId],
[Extent1].[CredentialId] AS [CredentialId],
[Extent1].[DisciplineId] AS [DisciplineId],
[Extent1].[UnitId] AS [UnitId],
[Extent1].[YearsOfService] AS [YearsOfService],
[Extent1].[Person_Id] AS [Person_Id]
FROM [dbo].[Nurse] AS [Extent1]}
以下是 table:
CREATE TABLE [dbo].[Person]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK__Person] PRIMARY KEY CLUSTERED ([Id] ASC)
)
CREATE TABLE [dbo].[Nurse]
(
[NurseId] BIGINT NOT NULL,
CONSTRAINT [PK_Nurse] PRIMARY KEY ([NurseId]),
CONSTRAINT [FK_Nurse_Person] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Person] ([Id])
)
和实体:
public class Person
{
[Key]
public long Id { get; set; }
}
public class Nurse
{
[Key]
public long NurseId { get; set; }
public long? CredentialId { get; set; }
public long? DisciplineId { get; set; }
public long? UnitId { get; set; }
public int? YearsOfService { get; set; }
[ForeignKey("PersonId")]
public virtual Person Person { get; set; }
[ForeignKey("CredentialId")]
public virtual Credential Credential { get; set; }
[ForeignKey("DisciplineId")]
public virtual Discipline Discipline { get; set; }
[ForeignKey("UnitId")]
public virtual Unit Unit { get; set; }
}
ApplicationDBContext:
public class ApplicationDBContext : DbContext
{
public ApplicationDBContext() : base("ApplicationDbContext")
{
}
public DbSet<Nurse> Nurses { get; set; }
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Nurse>().HasKey(n => n.NurseId);
}
}
是否可以这样做,或者我是否需要参考 Nurse in my Person table 并使用我在网上看到的内容?
我认为您的问题是您使用的 PersonId 在 Nurse 中具有主键。尝试给 Nurse 一个自己的 Id。每个 table 都有自己的 ID 是个好主意。 EF 存在 table 或没有唯一主键的视图的问题。
CREATE TABLE [dbo].[Person]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK__Person] PRIMARY KEY CLUSTERED ([Id] ASC)
)
CREATE TABLE [dbo].[Nurse]
(
[Id] BIGINT IDENTITY (1, 1) NOT NULL,
[PersonId] BIGINT unique NOT NULL,
CONSTRAINT [PK_Nurse] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Nurse_Person] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Person] ([Id])
)
对于那些偶然发现这一点的人。我找到了答案 here。我贴的流利的api很接近,应该是:
modelBuilder.Entity<Nurse>().HasRequired(n => n.Person).WithOptional();