【问题标题】:Multiple Foreign Keys to one entity一个实体的多个外键
【发布时间】:2018-07-15 19:08:17
【问题描述】:

我正在开发一个系统,志愿者可以申请成为教堂仪式/约会的一部分。

我想拥有它,以便多个志愿者可以参加一个仪式,可能是 1 人,也可能是 4 人。我在 SO 上看到过各种示例,它们只使用两个外键,但我无法理解两个以上。我知道我需要逆属性,但我很困惑。

这是我需要的两个实体。我想我需要在志愿者中作为 ICollection 进行预约/仪式。我可能还差得很远,我不太确定。

public class Volunteer
{
    [Key]
    public int VolunteerId { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }

    public bool GardaVetted { get; set; }

    public string VolunteerRole { get; set; }

    public string VolunteerPhoneNumber { get; set; }

    [ForeignKey("Church")]
    public int ChurchId { get; set; }

    [ForeignKey("Appointments")]
    public int AppointmentId { get; set; }

    //Foreign Key
    public virtual Church Church { get; set; }

    public virtual ICollection<Appointments> Appointments { get; set; }

}

public class Appointments
{
    [Key]
    public int AppointmentId { get; set; }

    public string DetailsOfAppointment { get; set; }

    public int? Fee { get; set; }

    public string RoomType { get; set; }

    public string NameOfApplicant { get; set; }

    public string ApplicantPhoneNumber { get; set; }

    public string ApplicantEmail { get; set; }

    [DataType(DataType.DateTime)]
    [DisplayFormat(ApplyFormatInEditMode = true,DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
    public DateTime DateOfAppointment { get; set; }

    public string ThemeColour { get; set; }

    public Boolean Confirmed { get; set; }

    [ForeignKey("Admins")]
    public int AdministrationId { get; set; }

    [ForeignKey("Church")]
    public int ChurchId { get; set; }

    //[ForeignKey("Volunteers")]
    //public int VolunteerId { get; set; }

    public virtual Church Church { get; set; }

    public virtual Administration Admins { get; set; }

    //public virtual Volunteer Volunteers { get; set; }
}

【问题讨论】:

  • 不太确定这与 sql server 或数据库设计有什么关系。发布的所有内容都是 dotnet 代码。
  • @SeanLange 我的错,更改了标签
  • @AnnaDoe 您可能还想添加一个实体框架标签
  • 您是否打算允许一个志愿者有多个约会,以及一个涉及多个志愿者的约会?如果是这样,那么快速搜索 entity framework many-to-many relationship 应该会有所帮助
  • 是的,正如 Andrew 所说,这听起来更像是多对多。在每一侧放置一个集合,EF 将进行链接。你也有一个与教堂有联系的志愿者?这是正确的,还是您只想将活动与教堂联系起来?

标签: c# asp.net entity-framework orm ef-code-first


【解决方案1】:

据我所知,从您的问题来看,您想要从约会到志愿者的一对多关系。

只需将志愿者的 ICollection 导航属性放入约会模型中即可。这将被视为一对多关系。像一个约会可以有资格获得多个/多个志愿者

class Volunteer
{
  //properties
}

class Appointments
{
  //other properties
  //....
  //. . .
  //Navigation property/foreign key for Volunteers(one-many)1 appointments=many volunteers
  ICollection<Volunteer> Volunteers {get;set;}
}

【讨论】:

    【解决方案2】:

    你提到了一个仪式,后来没有再提到。我认为仪式就是你在别处所谓的约会。

    这是我从你的课程中读到的,我认为你的定义是正确的。

    您似乎拥有一系列教堂。每个教会都有零个或多个志愿者,每个志愿者都属于一个教会。这称为一对多关系

    每个志愿者可以有零个或多个约会。

    不清楚: - 一个约会是否只属于一个志愿者,或者几个志愿者可以参加同一个约会? - 申请人是志愿者吗?在这种情况下:不要将志愿者财产复制给申请人 - 参加聚会的所有义工是否都属于同一个教会,还是聚会的参加者可以属于不同的教会?

    在我看来,来自不同教会的人可能参加同一个会议更合乎逻辑。这意味着每个志愿者可以参加零个或多个会议(约会),每个会议都有零个或多个志愿者参加,可能来自不同的教会:这是真正的多对多关系。

    显然,教会和任命之间也有关系。目前尚不清楚这是否是主持约会的教堂,或者这是否是约会的地点。无论如何,让我们假设每个教堂都有零个或多个约会,并且每个约会都在一个教堂举行

    如果您关注the entity framework code first conventions,,以下内容就足够了:

    class Church
    {
        public int Id {get; set;}
    
        // every Church has zero or more Volunteers:
        public virtual ICollection<Volunteer> Volunteers {get; set;}
    
        // every Church hosts zero or more Appointments:
        public virtual ICollection <Appointment> Appointments {get; set;}
    
        ... // other Church properties
    }
    
    class Volunteer
    {
        public int Id {get; set;}
    
        // every Volunteer belongs to exactly one Church using foreign key
        public int ChurchId {get; set;}
        public virtual Church Church {get; set;}
    
        // every Volunteer has zero or more Appointments:
        public virtual ICollection<Appointment> Appointments {get; set;}
    
        ... // other Properties
    }
    
    class Appointment
    {
        public int Id {get; set;}
    
        // every Appointment is attended by one or more Volunteers (many-to-many)
        public virtual ICollection<Volunteer> Volunteers {get; set;}
    
        // every Appointment is hosted by exactly one Church using foreign key
        public int ChurchId {get; set;}
        public virtual Church Church {get; set;}
    
        ... // other properties
    }
    
    class MyDbContext : DbContext
    {
        public DbSet<Church> Churches {get; set;}
        public DbSet<Volunteer> Volunteers {get; set;}
        public DbSet<Appointment> Appointments {get; set;}
    }
    

    因为我遵循实体框架约定,所以这是所有实体框架需要知道的,以了解我计划了 Church 和 Volunteers 之间的一对多以及 Volunteers 和 Appointments 之间的多对多。 Entity Framework 将识别主键和外键,甚至会创建junction table for your many-to-many relationship。不需要属性也不需要流畅的 API。只有当你想要不同的表名或列名时,你才需要属性或流利的 api。

    用法:

    给我所有在圣巴塞洛缪教堂举行的志愿者“约翰”的约会:

    var appointmentsofJohnInStBarth = dbContext.Appointments
        .Where(appointment => Appointment.Volunteer.Name = "John"
              && appointment.Church.Name = "Saint Bartholomew")
        .Select(appointment => new
        {
            StartTime = appointment.StartTime,
            EndTime = appointment.EndTime,
    
            Description = appointment.Description,
            Attendants = appointment.Volunteers
                .Select(volunteer => new
                {
                    Name = volunteer.Name,
                    Function = volunteer.Function,
                    Email = volunteer.Email,
                    ...
                 })
                 .ToList(),
        });
    

    因为您的 DbContext 知道志愿者/教堂/约会之间的关系,所以 DbContext 知道何时为一对多执行 GroupJoin 或为多对多关系执行 JunctionTable 上的连接,无需您必须指定必须执行哪些连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      • 2013-11-20
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 2012-10-07
      相关资源
      最近更新 更多