Entity Framework 代码优先以意外方式生成 tables/keys
Entity Framework code-first generating tables/keys in an unexpected manner
我有很多 类 表,但有三个让我头疼:Person、Task 和 Role,这是它们的代码:
public class Person : BaseModel
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string Title { get; set; }
public ICollection<TestEvent> TestEventsLed { get; set; }
public ICollection<TestEvent> TestEventsCreated { get; set; }
public ICollection<Program> ProgramsLed { get; set; }
public ICollection<Task> TasksCreated { get; set; }
public ICollection<PersonalEvent> PersonalEventsCreated { get; set; }
public virtual ICollection<Role> RolesHeld { get; set; }
public virtual ICollection<Task> TasksAssigned { get; set; }
}
public class Role : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> PeopleWithThisRole { get; set; }
}
public class Task : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime SuspenseDatetime { get; set; }
public DateTime CreatedDatetime { get; set; }
public int CreatedById { get; set; }
public bool Completed { get; set; }
public bool Archived { get; set; }
public Person CreatedBy { get; set; }
public virtual ICollection<Person> PeopleAssigned { get; set; }
}
我最终得到的大部分是我想要的,除了一些小问题:
Expected: Actual:
- People should have 0 foreign keys, just - People has 1 FK and 1 extra column out of
2 many-to-manys for RolesHeld and nowhere: Task_Id and the FK is for that
TasksAssigned new column referencing Id in Tasks?
- Task should have 1 foreign key for - Task has 2 extra columns out of nowhere
CreatedById linked to a Person called Person_Id and Person_Id1 and then
identical foreign keys attached to them
(and it has the expected CreatedById FK)
- There should be a RolePersons table - This part happened correctly and with the
with 2 FKs to represent the many-to-many correct FKs to represent the many-to-many
- There should be a TaskPersons table - There is no new table at all for this
with 2 FKs to represent the many-to-many
奇怪的是,我以相同的方式做了其中一些(比如两个多对多关系),但只有 1 个结果是正确的?你能看出我做错了什么吗?
Entity Framework按惯例做事。
查看您的任务 class 和人员 class
public class Task : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime SuspenseDatetime { get; set; }
public DateTime CreatedDatetime { get; set; }
public int CreatedById { get; set; }
public bool Completed { get; set; }
public bool Archived { get; set; }
public Person CreatedBy { get; set; }
public virtual ICollection<Person> PeopleAssigned { get; set; }
}
public class Person : BaseModel
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string Title { get; set; }
public ICollection<TestEvent> TestEventsLed { get; set; }
public ICollection<TestEvent> TestEventsCreated { get; set; }
public ICollection<Program> ProgramsLed { get; set; }
public ICollection<Task> TasksCreated { get; set; }
public ICollection<PersonalEvent> PersonalEventsCreated { get; set; }
public virtual ICollection<Role> RolesHeld { get; set; }
public virtual ICollection<Task> TasksAssigned { get; set; }
}
在您的任务 Class 中,您正在放置 Person 对象以及 Person.That 的集合,我猜这就是让您头疼的原因。
如果你需要它们之间的多对多关系,那么你不应该把这个 属性 放在你的任务中 Class
public Person CreatedById { get; set; }
public Person CreatedBy { get; set; }
或者如果您需要它们之间的一对多关系,则从您的任务中删除此 属性 class
public virtual ICollection<Person> PeopleAssigned { get; set; }
有时默认映射不是我们想要的,所以我们必须明确地告诉 EF 我们需要什么。只需将此方法添加到您的 DbContext 中,它就会按要求工作:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasMany(p => p.TasksAssigned).WithMany(t => t.PeopleAssigned);
modelBuilder.Entity<Person>().HasMany(p => p.TasksCreated).WithRequired(t => t.CreatedBy).WillCascadeOnDelete(false);
}
我有很多 类 表,但有三个让我头疼:Person、Task 和 Role,这是它们的代码:
public class Person : BaseModel
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string Title { get; set; }
public ICollection<TestEvent> TestEventsLed { get; set; }
public ICollection<TestEvent> TestEventsCreated { get; set; }
public ICollection<Program> ProgramsLed { get; set; }
public ICollection<Task> TasksCreated { get; set; }
public ICollection<PersonalEvent> PersonalEventsCreated { get; set; }
public virtual ICollection<Role> RolesHeld { get; set; }
public virtual ICollection<Task> TasksAssigned { get; set; }
}
public class Role : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> PeopleWithThisRole { get; set; }
}
public class Task : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime SuspenseDatetime { get; set; }
public DateTime CreatedDatetime { get; set; }
public int CreatedById { get; set; }
public bool Completed { get; set; }
public bool Archived { get; set; }
public Person CreatedBy { get; set; }
public virtual ICollection<Person> PeopleAssigned { get; set; }
}
我最终得到的大部分是我想要的,除了一些小问题:
Expected: Actual:
- People should have 0 foreign keys, just - People has 1 FK and 1 extra column out of
2 many-to-manys for RolesHeld and nowhere: Task_Id and the FK is for that
TasksAssigned new column referencing Id in Tasks?
- Task should have 1 foreign key for - Task has 2 extra columns out of nowhere
CreatedById linked to a Person called Person_Id and Person_Id1 and then
identical foreign keys attached to them
(and it has the expected CreatedById FK)
- There should be a RolePersons table - This part happened correctly and with the
with 2 FKs to represent the many-to-many correct FKs to represent the many-to-many
- There should be a TaskPersons table - There is no new table at all for this
with 2 FKs to represent the many-to-many
奇怪的是,我以相同的方式做了其中一些(比如两个多对多关系),但只有 1 个结果是正确的?你能看出我做错了什么吗?
Entity Framework按惯例做事。
查看您的任务 class 和人员 class
public class Task : BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime SuspenseDatetime { get; set; }
public DateTime CreatedDatetime { get; set; }
public int CreatedById { get; set; }
public bool Completed { get; set; }
public bool Archived { get; set; }
public Person CreatedBy { get; set; }
public virtual ICollection<Person> PeopleAssigned { get; set; }
}
public class Person : BaseModel
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string Title { get; set; }
public ICollection<TestEvent> TestEventsLed { get; set; }
public ICollection<TestEvent> TestEventsCreated { get; set; }
public ICollection<Program> ProgramsLed { get; set; }
public ICollection<Task> TasksCreated { get; set; }
public ICollection<PersonalEvent> PersonalEventsCreated { get; set; }
public virtual ICollection<Role> RolesHeld { get; set; }
public virtual ICollection<Task> TasksAssigned { get; set; }
}
在您的任务 Class 中,您正在放置 Person 对象以及 Person.That 的集合,我猜这就是让您头疼的原因。
如果你需要它们之间的多对多关系,那么你不应该把这个 属性 放在你的任务中 Class
public Person CreatedById { get; set; }
public Person CreatedBy { get; set; }
或者如果您需要它们之间的一对多关系,则从您的任务中删除此 属性 class
public virtual ICollection<Person> PeopleAssigned { get; set; }
有时默认映射不是我们想要的,所以我们必须明确地告诉 EF 我们需要什么。只需将此方法添加到您的 DbContext 中,它就会按要求工作:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasMany(p => p.TasksAssigned).WithMany(t => t.PeopleAssigned);
modelBuilder.Entity<Person>().HasMany(p => p.TasksCreated).WithRequired(t => t.CreatedBy).WillCascadeOnDelete(false);
}