C# 使用EF Core在另一个实体中创建唯一密钥的外键
我有一个这样的程序实体C# 使用EF Core在另一个实体中创建唯一密钥的外键,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,我有一个这样的程序实体 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; }
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; }
}
将程序代码创建为此实现的唯一键
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Program>().HasAlternateKey(d => d.ProgramCode).HasName("AK_ProgramCode");
}
在程序表中有程序代码的FirstChoiceID、SecondChoiceID和ThirdChoiceID。
这是我的问题
join
。因为您有3个相关属性,所以还需要3个join
s:
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.Name
,secondChoice.Name
等
但一旦定义了导航属性,您就不需要EF中的所有内容,这将导致我们:
(2) 是否可以从AppliantProgram为程序创建导航属性
(3) 我如何根据应链接到Program.ProgramCode而不使用Program.Id的选项Id在应用程序之间创建外键
这两者是相互关联的。虽然可以在不使用navigation属性的情况下定义FK,但navigation属性允许您简单地访问LINQ查询中的相关实体属性,以及简单地将相关实体作为使用它的实体的一部分加载
首先在applicationProgram
类中添加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);
与(1)类似,您可以投影整个相关对象或仅投影所需的属性
或者,您可以通过向applicationProgram
查询添加Include
运算符(所谓的)来获取具有填充的相关Program
属性的applicationProgram
实例:
这非常有效,帮助我理解了ef core中的一些概念。非常感谢。我尝试了这两种方法作为学习工具。我更喜欢第二种选择。只需重命名为程序FirstProgram{get;set;}公共程序SecondProgram{get;set;}公共程序ThirdProgram{get;set;},这样就不会丢失已存储在FirstChoiceID、SecondChoiceID和ThirdChoiceID中的数据
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);
var query =
from applicantProgram in db.ApplicantPrograms
select new
{
applicantProgram,
firstChoice = applicantProgram.FirstChoice,
secondChoice = applicantProgram.SecondChoice,
thirdChoice = applicantProgram.ThirdChoice,
};
var query = db.ApplicantPrograms
.Include(applicantProgram => applicantProgram.FirstChoice)
.Include(applicantProgram => applicantProgram.SecondChoice)
.Include(applicantProgram => applicantProgram.ThirdChoice);