【问题标题】:How do I map a 1 to 0 or 1 relationship in Fluent API in EF 6如何在 EF 6 的 Fluent API 中映射 1 到 0 或 1 的关系
【发布时间】:2019-06-03 13:36:30
【问题描述】:

已编辑

我有 2 张桌子,护士和人。 Person 与 Nurse 具有 1 对 0 或 1 的关系。换句话说,我申请中的一些人也将是护士。我想在两个表中使用相同的主键。当我运行查询 Nurse 表的代码时,我最终得到一个“System.Data.Entity.Core.EntityCommandExecutionException”,然后是内部异常:“SqlException: Invalid column name 'Person_Id'。”

我的 Nurse 模型中没有“Person_Id”字段。生成的查询似乎已添加它。我的模型定义中一定遗漏了一些东西,因为删除“public virtual Person Person { get; set; }”会使查询正确生成。 EF 似乎对 PK 在 Person 表中是 Id 而在 Nurse 表中是 NurseId 这一事实感到困惑。

我在互联网上找到了多个地方,向您展示了如何使用 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]}

这是表格:

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);
    }
}

是否可以这样做,或者我需要在我的 Person 表中引用 Nurse 并使用我在网上看到的内容?

【问题讨论】:

标签: c# asp.net-mvc entity-framework-6


【解决方案1】:

我认为您的问题是您使用的 PersonId 在 Nurse 中具有主键。尝试给 Nurse 自己的 ID。每个表都有自己的 ID 是个好主意。 EF 在没有唯一主键的表或视图方面存在问题。

    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])
)

【讨论】:

  • 这是我希望避免做的事情,因为理论上我最终可能会导致一个人被绑定到多个 Nurse 记录。
  • 在这种情况下,在 Nurse 表中添加 PersionId 唯一的关键字。[PersonId] BIGINT 唯一 NOT NULL,我将编辑我的答案。
【解决方案2】:

对于那些偶然发现这一点的人。我找到了答案here。我贴的fluent api很接近,应该是:

modelBuilder.Entity<Nurse>().HasRequired(n => n.Person).WithOptional();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多