Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EF Core在另一个实体中创建唯一密钥的外键_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

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。 这是我的问题

  • 如何从applicationProgram获取Program.Name属性,并知道要链接到Program.ProgramCode的第一个ChoiceID
  • 是否可以从AppliantProgram为程序创建导航属性
  • 我如何根据应链接到Program.ProgramCode而不使用Program.Id的选项Id在应用程序之间创建外键
  • 谢谢你停下来读这篇文章

    (1) 如何从applicationProgram获取Program.Name属性,并知道要链接到Program.ProgramCode的第一个ChoiceID

    这里没有特定于EF的内容,您可以使用典型的数据关联运算符-
    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);