gpt4 book ai didi

c# - 使用 EF Core 在另一个实体中创建唯一键的外键

转载 作者:行者123 更新时间:2023-12-04 03:11:44 24 4
gpt4 key购买 nike

我有一个这样的程序实体

public class Program : IEntityBase
{
public int Id { get; set; }
public string ProgramCode { get; set; }
public string Name { get; set; }
public int DegreeTypeID { get; set; }
public DegreeType DegreeType { get; set; }
}

使用此实现将 programCode 创建为唯一键

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Program>().HasAlternateKey(d => d.ProgramCode).HasName("AK_ProgramCode");
}

我有另一个具有此定义的实体 ApplicantProgram

public class ApplicantProgram : IEntityBase
{
public int Id { get; set; }
public int ApplicantID { get; set; }
public Applicant Applicant { get; set; }
[Required]
public string FirstChoiceID { get; set; }
[Required]
public string SecondChoiceID { get; set; }
[Required]
public string ThirdChoiceID { get; set; }
public string SessionID { get; set; }
}

在程序表中有 FirstChoiceID、SecondChoiceID 和 ThirdChoiceID 具有 ProgramCode。现在这些是我的问题,

  1. 如何从 ApplicantProgram 获取 Program.Name 属性,知道要链接到 Program.ProgramCode 的 FirstChoiceID?
  2. 是否可以创建导航属性以从 ApplicantProgram 进行编程?
  3. 我如何根据应链接到 Program.ProgramCode 而不使用 Program.Id 的 ChoiceID 创建从 ApplicantProgram 到 Program 的外键?

感谢您停下来阅读本文。

最佳答案

(1) How do I get Program.Name property from ApplicantProgram knowing the FirstChoiceID that is to link to Program.ProgramCode?

此处没有特定于 EF 的内容,您可以使用典型的数据关联运算符 - join。仅仅因为您有 3 个相关属性,您还需要 3 个 join:

var query =
from applicantProgram in db.ApplicantPrograms
join firstChoice in db.Programs on applicantProgram.FirstChoiceID equals firstChoice.ProgramCode
join secondChoice in db.Programs on applicantProgram.SecondChoiceID equals secondChoice.ProgramCode
join thirdChoice in db.Programs on applicantProgram.ThirdChoiceID equals thirdChoice.ProgramCode
select new
{
ApplicantProgram = applicantProgram,
FirstChoice = firstChoice,
SecondChoice = secondChoice,
ThirdChoice = thirdChoice,
};

select 中,您可以获得上面的所有相关对象,或特定属性,如 firstChoice.NamesecondChoice.Name 等.

但是一旦您定义了导航属性,您就不需要 EF 中的所有这些,这导致我们:

(2) Is it possible to create a Navigation property to program from ApplicantProgram?

(3) How do I create a foreign key from ApplicantProgram to Program based off the ChoiceIDs that should link to Program.ProgramCode without using Program.Id?

这两者是相互关联的。虽然可以在没有导航属性的情况下定义 FK,但导航属性将允许您简单地访问 LINQ 查询中的相关实体属性,以及简单地预加载相关实体作为使用它的实体的一部分。

首先在 ApplicantProgram 类中添加 3 个导航属性(每个 FK 属性一个):

public Program FirstChoice { get; set; }
public Program SecondChoice { get; set; }
public Program ThirdChoice { get; set; }

以及以下流畅的配置:

builder.Entity<ApplicantProgram>()
.HasOne(e => e.FirstChoice)
.WithMany()
.HasForeignKey(e => e.FirstChoiceID)
.HasPrincipalKey(e => e.ProgramCode)
.OnDelete(DeleteBehavior.Restrict);

builder.Entity<ApplicantProgram>()
.HasOne(e => e.SecondChoice)
.WithMany()
.HasForeignKey(e => e.SecondChoiceID)
.HasPrincipalKey(e => e.ProgramCode)
.OnDelete(DeleteBehavior.Restrict);

builder.Entity<ApplicantProgram>()
.HasOne(e => e.ThirdChoice)
.WithMany()
.HasForeignKey(e => e.ThirdChoiceID)
.HasPrincipalKey(e => e.ProgramCode)
.OnDelete(DeleteBehavior.Restrict);

我们这里有标准的多对一关系配置 - HasOne(...) 指定引用导航属性WithMany() 指定没有对应的集合导航属性HasForeighKey(...) 指定对应的 FK 属性,以及与同一个表的多个关系的典型关闭级联删除以避免多个级联路径问题。

具体的想法(以及 EF Core 对 EF6 的改进)是 HasPrincipalKey(...) 方法,它允许您指定其他唯一的 key 属性而不是 PK(默认情况下)由 FK 关系使用。在另一端与 HasAlternateKey(...) 结合使用可以实现所需的 FK 关系设置。

基本上就是这样。现在来自 (1) 的查询可以很简单

var query =
from applicantProgram in db.ApplicantPrograms
select new
{
applicantProgram,
firstChoice = applicantProgram.FirstChoice,
secondChoice = applicantProgram.SecondChoice,
thirdChoice = applicantProgram.ThirdChoice,
};

与 (1) 类似,您可以投影整个相关对象或仅投影您需要的属性。

或者,您可以通过向 ApplicantProgram 添加 Include 运算符来获取具有相关 Program 属性的 ApplicantProgram 实例查询(即所谓的 eager loading ):

var query = db.ApplicantPrograms
.Include(applicantProgram => applicantProgram.FirstChoice)
.Include(applicantProgram => applicantProgram.SecondChoice)
.Include(applicantProgram => applicantProgram.ThirdChoice);

关于c# - 使用 EF Core 在另一个实体中创建唯一键的外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44742228/

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