【问题标题】:EF Core 3.1 - How to use an already combined PK for another combined PK?EF Core 3.1 - 如何将已经组合的 PK 用于另一个组合的 PK?
【发布时间】:2020-10-25 09:27:07
【问题描述】:

我目前正在学习使用 EF,我有以下关系:

一个警报有 1 到 n 次出现。 每次出现都可以有 0 到 n 个值(附加信息)。

public class Alert
{
    // PK
    public int AlertId { get; set; }

    // Attributes
    public int CurrentAlertLevel { get; set; }

    public DateTime TimeRaised { get; set; }
    public DateTime TimeLastRaised { get; set; }

// Some other attributes ommitted...        

    // Relations
    public ICollection<AlertOccurrence> Occurrences { get; set; }
}

public class AlertOccurrence
{
    // Relations which are part of the primary key
    public int AlertId { get; set; }

    // Attributes
    public int Ordinal { get; set; }

// some ommited attributes

    // Relations
    public ICollection<AlertDetailValue> AlertDetailValues { get; set; }
}

public class AlertDetailValue
{
    public int AlertDetailValueId { get; set; }
    public int Order { get; set; }
    public string Value { get; set; }
}

在数据库上下文 OnModelCreating 中,我正在为 AlertOccurence 设置组合 PK:

modelBuilder.Entity<AlertOccurrence>().HasKey(ao => new {ao.AlertId, ao.Ordinal});

虽然这似乎可行 - 我实际上想要存档的是相同的关系,而不需要将 AlertDetailValueId 作为 PK。 EF 生成的表还包括 AlertOccurrenceAlertId 和 AlertOccurrenceOrdinal,这对我来说似乎是浪费空间。

所以我想做的是: 具有 AlertDetailValue 的组合主键,由 AlertDetailValue.Order 和 AlertOccurence 的(已组合的)PK 而不是“人工”AlertDetailValueId 组成。这有可能吗?

我的部分问题可能是使用 fluent api 定义的 PK 不是数据类的一部分。所以可能另一个要问的问题是:有没有办法在实体类中使用 fluent api 中定义的键?

或者我是否需要在我的实体类 AlertDetailValue 中包含 AlertOccurrenceAlertId 和 AlertOccurrenceOrdinal - 但是我该如何链接它们?

正如我所说,我仍在努力了解 EF,因此虽然可能有更好的方法来做到这一点,但我对这种特殊的关系/组合(组合)PK 感兴趣,即使它可能是学术性的。 .. 任何帮助将不胜感激。

【问题讨论】:

  • 如果 EF 生成的表包含 AlertOccurrenceAlertIdAlertOccurrenceOrdinal 等列,那是因为您还没有自己定义/配置外键,而 EF 正在尝试为您完成使用其命名约定。

标签: entity-framework-core


【解决方案1】:

尝试解释我尝试做什么以及我的问题是什么 - 并好好洗个澡 - 帮助我向谷歌提出不同的问题并更多地关注外键。 并不是我之前没有尝试过google...我只是问错了问题..

所以我发现了这个: Mapping composite foreign key to composite primary key where the foreign key is also a primary key (在尝试新方法时,@atiyar 还暗示缺少外键......)

我的新解决方案是更改 AlertDetailValue 以有意包含构建 Occurence PK 的部分:

    public class AlertDetailValue
    {
         // relations will be set up in fluent api in OnModelCreating of db context
        public int AlertOccurenceAlertId { get; set; }
        public int AlertOccurenceOrdinal { get; set; }

        public int Order { get; set; }
        public string Value { get; set; }
    }

然后告诉 EF 有一个组合的 PK 和一个组合的外键:

            modelBuilder.Entity<AlertDetailValue>().HasKey(adv => new { adv.AlertOccurenceAlertId, adv.AlertOccurenceOrdinal, adv.Order  });

            modelBuilder.Entity<AlertOccurrence>().HasMany<AlertDetailValue>(adv => adv.AlertDetailValues).WithOne()
                .HasForeignKey(adv => new {adv.AlertOccurenceAlertId, adv.AlertOccurenceOrdinal});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多