简体   繁体   English

使用Fluent API的Entity Framework 6代码优先关系

[英]Entity Framework 6 code-first relations with Fluent API

I have 3 related tables in an existing database. 我在现有数据库中有3个相关表。 Many-to-Many (Many Person Many Group) and a table between - Event, witch ralate these two tables. 多对多(Many Person Many Group)和一个表之间-事件,女巫整理了这两个表。

public class Person
    {
        public int PersonID { get; set; }
        public string No { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual ICollection<Event> Events { get; set; }
    }
   public class Event
    {
        public int EventID { get; set; }
        public string EventData { get; set; }
        public int PersonID { get; set; }
        public int GroupID { get; set; }
        public virtual Person Person { get; set; }
        public virtual Group Group { get; set; }
   }

   public class Group
    {
        public int GroupID { get; set; }
        public string GroupName { get; set; }
        public virtual ICollection<Event> PersonGroup { get; set; }
    }

I ddescribed relations using Fluent API. 我使用Fluent API描述了关系。 First I declared PK's 首先我宣布PK

modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID });

modelBuilder.Entity<Event>()
.HasKey(k => k.EventID);

modelBuilder.Entity<Group>()
.HasKey(k => k.GroupID });

Now foreign keys: Person has many Events 现在外键:人有很多事件

modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID })
.HasMany(k => k.Events)
.WithRequired()
.HasForeignKey(f => f.PersonID);

In Event class I have Person (and all its parameters) 在事件类中,我有Person(及其所有参数)

modelBuilder.Entity<Event>()
.HasRequired(s => s.Person)
.WithMany()
.HasForeignKey(fk => fk.PersonID);

Also I need a Group with all data: 我还需要一个包含所有数据的组:

modelBuilder.Entity<Event>()
.HasOptional(s => s.Group)
.WithMany()
.HasForeignKey(fk => fk.GroupID });

At least I need a Person group participating in an Event 至少我需要一个参加活动的人员小组

modelBuilder.Entity<Group>()
.HasKey(k =>k.GroupID })
.HasMany(k => k.PersonGroup)
.WithOptional()
.HasForeignKey(fk => fk.GroupID);

It seems I have everything I need, but I need one mo collection (Group of persons with their names) 似乎我已拥有所需的一切,但我需要一个月收藏(带有姓名的一群人)

What I get through PersonGroup relation I have all events but also need to get Persons. 我通过PersonGroup关系得到的内容我有所有事件,但也需要获得Persons。 Could You help? 你能帮忙吗?

Edit 编辑

I just realize it's not a typical many-to-many, since your Event-Group relation is optional. 我只是意识到这不是典型的多对多事件,因为您的事件组关系是可选的。 Is this intended? 这是故意的吗?

Maybe your model should be changed to reflect a more natural event structure: 也许应该更改模型以反映更自然的事件结构:

Group-Person: many-to-many 小组人员:多对多

Event-Group: many-to-many 事件组:多对多

Event-Person: no direct relation, only via groups; 事件人员:没有直接关系,只能通过小组进行; alternative many-to-many 替代多对多

The way your model is currently designed, a single event entry can't be related to more than one group and one person and a person can't be part of a group unless they are associated in the context of an event entry. 当前设计模型的方式是,单个事件条目不能与多个组相关,并且一个人和一个人不能成为组的一部分,除非它们在事件条目的上下文中相关联。


Basically, the thing you ask for is not directly available, because you decided to explicitely create the many-to-many table with additional properties. 基本上,您要的东西不是直接可用的,因为您决定显式地创建具有其他属性的多对多表。

However, in queries you can always write a select to get the persons collection 但是,在查询中,您始终可以编写选择以获取人员集合

db.Groups.Select(g => new {Group = g, PeopleInGroup = g.PersonGroup.Select(ev => ev.Person)})

Few side-notes regarding your model: 关于您的模型的一些注释:

  • Consider removing EventID and instead use modelBuilder.Entity<Event>().HasKey(k => new { k.PersonID, k.GroupID }) , like a typical many-to-many table would be designed. 考虑删除EventID ,而是使用modelBuilder.Entity<Event>().HasKey(k => new { k.PersonID, k.GroupID }) ,就像设计典型的多对多表一样。
  • Mention reverse properties in fluent api: 在流利的api中提及反向属性:

.

modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID })
.HasMany(k => k.Events)
.WithRequired(e => e.Person)
.HasForeignKey(f => f.PersonID);

// redundant with the previous configuration
modelBuilder.Entity<Event>()
.HasRequired(s => s.Person)
.WithMany(p => p.Events)
.HasForeignKey(fk => fk.PersonID);

// same to be done for groups

In order to have a convenient access to the associated people of a group, you could create a not-mapped property getter which wraps the necessary query: 为了方便地访问组中的关联人员,可以创建一个未映射的属性getter,该属性包装必需的查询:

public class Group
{
    public int GroupID { get; set; }
    public string GroupName { get; set; }
    public virtual ICollection<Event> PersonGroup { get; set; }

    [NotMapped]
    public IEnumerable<Person> PersonsInGroupEvents
    {
        return PersonGroup.Select(ev => ev.Person);
    }
}

// or fluent api way of NotMapped:
modelBuilder.Entity<Group>()
    .Ignore(x => x.PersonsInGroupEvents);

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

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