简体   繁体   English

一个实体的多个外键

[英]Multiple Foreign Keys to one entity

I am developing a system that volunteers can apply to be a part of ceremonies/appointments for a church. 我正在开发一种系统,志愿者可以将其申请成为教堂的仪式/任命的一部分。

I want to have it so multiple volunteers can be part of a ceremony, might be 1 or could be 4. I've seen various examples on SO that use just two foreign keys but I just can't wrap my head around more than two. 我想要这样,以便多个志愿者可以参加仪式,可能是1或可能是4。我在SO上看到过各种示例,它们仅使用两个外键,但是我不能将头缠绕在两个以上。 I know I need inverse property but I'm just confused. 我知道我需要逆属性,但我只是感到困惑。

Here's the two entities I need. 这是我需要的两个实体。 I think I need to have Appointment/Ceremony in the volunteer as an ICollection. 我想我需要作为ICollection参加志愿者的约会/仪式。 I may be way off, I'm not too sure. 我可能不太了解,我不太确定。

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; }
}

As far I understand from your question is that, you want a one to many relationship from Appointments to Volunteer. 我从您的问题中了解到,您希望从任命到志愿人员之间存在一对多的关系。

Just put a ICollection navigation property of Volunteers in the Appointments model. 只需在“约会”模型中放入“志愿者”的ICollection导航属性。 Which will be considered as one to many relation. 这将被视为一对多关系。 Like one Appointment can be eligible for multiple/many volunteers 就像一次任命可以有多个/许多志愿者的资格

class Volunteer
{
  //properties
}

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

You mention a Ceremony which is later not mentioned again. 您提到了一个仪式,后来不再提及。 I assume a Ceremony is what you call an Appointment elsewhere. 我假设一个仪式就是您在其他地方所说的约会。

This is what I read from your classes, and what I think you have defined correctly. 这是我从您的班级中学到的,也是我认为您已正确定义的内容。

You seem to have a collection of Churches. 您似乎有一些教堂。 Every Church has zero or more Volunteers and every Volunteer belongs to exactly one Church. 每个教会都有零个或多个志愿者,每个志愿者恰好属于一个教会。 This is called a one-to-many relationship 这称为一对多关系

Every Volunteer can have zero or more Appointments. 每个志愿者可以有零个或多个约会。

Unclear: - does an Appointment belong to only one Volunteer, or can several Volunteers attend the same Appointment? 不清楚:-约会仅属于一个志愿者,还是几个志愿者可以参加同一约会? - Is the applicant a Volunteer? -申请人是志愿者吗? In that case: don't copy Volunteer properties to an Applicant - Do all Volunteers that attend a meeting belong to the same Church, or can the attendants from a meeting belong to different Churches? 在那种情况下:不要将志愿者属性复制到申请人-参加会议的所有志愿者是否都属于同一教会,或者会议参加者可以属于不同的教会吗?

It seems to me more logical that people from different Churches might attend the same meeting. 在我看来,来自不同教会的人们可能参加同一会议更合乎逻辑。 That means that every Volunteer can attend zero or more meetings (Appointments), and every meeting is attended by zero or more Volunteers, possibly from different Churches: this is a true many-to-many relationship. 这意味着每个志愿人员都可以参加零个或多个会议(约会),并且每个会议都有零个或多个志愿人员(可能来自不同教会)参加:这是一种真正的多对多关系。

Apparently there is also a relation between Churches and Appointments. 显然,教会与任命之间也存在关系。 It is unclear whether this is the Church who hosts the appointment, or whether this is the location of the Appointment. 目前尚不清楚是任命的教会是教堂,还是任命的地点。 Anyway, let's assume that every Church hosts zero or more Appointments and every Appointment is held at exactly one Church 无论如何,我们假设每个教堂拥有零个或多个约会,并且每个约会仅在一个教堂中举行

If you'd follow the entity framework code first conventions, the following would be enough: 如果您遵循实体框架代码优先约定,那么下面的内容就足够了:

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;}
}

Because I followed the entity framework conventions, this is all entity framework needs to know to understand that I planned a one-to-many between Church and Volunteers and a many-to-many between Volunteers and Appointments. 因为我遵循实体框架约定,所以这是所有实体框架需要了解的内容,以了解我计划在教堂和志愿者之间进行一对多的计划,并在志愿者和任命之间进行多对多的计划。 Entity Framework will recognize the primary and foreign keys, and will even create the junction table for your many-to-many relationship . 实体框架将识别主键和外键,甚至会为您的多对多关系创建连接表 There is no need for attributes nor fluent API. 不需要属性也不需要流畅的API。 Only if you want different table names or column names you'll need attributes or fluent api. 仅当您想要不同的表名或列名时,才需要属性或流利的api。

Usage: 用法:

Give me all Appointments for Volunteer "John" that are held in St Bartholomew Church: 给我在圣巴塞洛缪教堂举行的“约翰”志愿人员的所有任命:

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(),
    });

Because your DbContext knows about the relations between the Volunteers / Churches / Appointments, the DbContext knows when to perform a GroupJoin for the one-to-many or a join on the JunctionTable for the many-to-many relationships, without you having to specify which joins must be performed. 因为您的DbContext知道了志愿者/教堂/任命之间的关系,所以DbContext知道了何时为一对多执行GroupJoin或在JunctionTable上为多对多关系执行联接,而无需指定必须执行哪些连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM