Entity Framework 6 个与 Fluent 的代码优先关系 API
Entity Framework 6 code-first relations with Fluent API
我在现有数据库中有 3 个相关的 table。
多对多(多人多组)和事件之间的 table, 评价这两个 tables。
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; }
}
我使用 Fluent API 描述了关系。
首先我宣布PK的
modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID });
modelBuilder.Entity<Event>()
.HasKey(k => k.EventID);
modelBuilder.Entity<Group>()
.HasKey(k => k.GroupID });
现在外键:
人有很多事件
modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID })
.HasMany(k => k.Events)
.WithRequired()
.HasForeignKey(f => f.PersonID);
在事件中 class 我有人物(及其所有参数)
modelBuilder.Entity<Event>()
.HasRequired(s => s.Person)
.WithMany()
.HasForeignKey(fk => fk.PersonID);
我还需要一个包含所有数据的组:
modelBuilder.Entity<Event>()
.HasOptional(s => s.Group)
.WithMany()
.HasForeignKey(fk => fk.GroupID });
至少我需要一个参与事件的人组
modelBuilder.Entity<Group>()
.HasKey(k =>k.GroupID })
.HasMany(k => k.PersonGroup)
.WithOptional()
.HasForeignKey(fk => fk.GroupID);
好像什么都有了,但是我需要一个mo合集(一群有名字的人)
我通过 PersonGroup 关系获得的信息 我拥有所有事件,但还需要获得 Persons。你能帮忙吗?
编辑
我只是意识到这不是典型的多对多关系,因为您的事件组关系是可选的。这是故意的吗?
也许您的模型应该更改以反映更自然的事件结构:
组-人:多对多
事件组:多对多
Event-Person:无直接关系,仅通过组;替代多对多
按照您的模型当前的设计方式,单个事件条目不能与多个组和一个人相关,并且一个人不能成为组的一部分,除非他们在某个上下文中相关联活动条目。
基本上,您要求的东西不能直接获得,因为您决定显式创建具有附加属性的多对多table。
但是,在查询中你总是可以写一个 select 来获取 persons 集合
db.Groups.Select(g => new {Group = g, PeopleInGroup = g.PersonGroup.Select(ev => ev.Person)})
关于您的模型的一些旁注:
- 考虑删除
EventID
并改为使用 modelBuilder.Entity<Event>().HasKey(k => new { k.PersonID, k.GroupID })
,就像设计典型的多对多 table 一样。
- 在 fluent 中提及反向属性 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
为了方便地访问组中的相关人员,您可以创建一个未映射的 属性 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);
我在现有数据库中有 3 个相关的 table。 多对多(多人多组)和事件之间的 table, 评价这两个 tables。
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; }
}
我使用 Fluent API 描述了关系。 首先我宣布PK的
modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID });
modelBuilder.Entity<Event>()
.HasKey(k => k.EventID);
modelBuilder.Entity<Group>()
.HasKey(k => k.GroupID });
现在外键: 人有很多事件
modelBuilder.Entity<Person>()
.HasKey(k => k.PersonID })
.HasMany(k => k.Events)
.WithRequired()
.HasForeignKey(f => f.PersonID);
在事件中 class 我有人物(及其所有参数)
modelBuilder.Entity<Event>()
.HasRequired(s => s.Person)
.WithMany()
.HasForeignKey(fk => fk.PersonID);
我还需要一个包含所有数据的组:
modelBuilder.Entity<Event>()
.HasOptional(s => s.Group)
.WithMany()
.HasForeignKey(fk => fk.GroupID });
至少我需要一个参与事件的人组
modelBuilder.Entity<Group>()
.HasKey(k =>k.GroupID })
.HasMany(k => k.PersonGroup)
.WithOptional()
.HasForeignKey(fk => fk.GroupID);
好像什么都有了,但是我需要一个mo合集(一群有名字的人)
我通过 PersonGroup 关系获得的信息 我拥有所有事件,但还需要获得 Persons。你能帮忙吗?
编辑
我只是意识到这不是典型的多对多关系,因为您的事件组关系是可选的。这是故意的吗?
也许您的模型应该更改以反映更自然的事件结构:
组-人:多对多
事件组:多对多
Event-Person:无直接关系,仅通过组;替代多对多
按照您的模型当前的设计方式,单个事件条目不能与多个组和一个人相关,并且一个人不能成为组的一部分,除非他们在某个上下文中相关联活动条目。
基本上,您要求的东西不能直接获得,因为您决定显式创建具有附加属性的多对多table。
但是,在查询中你总是可以写一个 select 来获取 persons 集合
db.Groups.Select(g => new {Group = g, PeopleInGroup = g.PersonGroup.Select(ev => ev.Person)})
关于您的模型的一些旁注:
- 考虑删除
EventID
并改为使用modelBuilder.Entity<Event>().HasKey(k => new { k.PersonID, k.GroupID })
,就像设计典型的多对多 table 一样。 - 在 fluent 中提及反向属性 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
为了方便地访问组中的相关人员,您可以创建一个未映射的 属性 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);