[英]seeding code first fluent api database EF code-first issues
我在播种和创建符合我需要的数据库时遇到了麻烦。 我有2个实体; 用户和部门。 用户需要一个部门,一个部门可以有多个用户,但同时,一个部门需要一个用户作为其DepartmentChief。 我可以弄清楚如何进行设置,每次尝试都会导致各种异常。
这是我的情况 :
public class FravaerContext : DbContext
{
public FravaerContext() : base("name=DefaultConnection")
{
Database.SetInitializer(new DBInitializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasRequired<Department>(u => u.Department).WithMany(d => d.Users).WillCascadeOnDelete(false);
modelBuilder.Entity<Department>().HasRequired(d => d.DepartmentChief);
//modelBuilder.Entity<Absence>().HasRequired<User>(a => a.User).WithMany(u => u.Absences).WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
public DbSet<Absence> Absences { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<User> Users { get; set; }
}
public class DBInitializer : DropCreateDatabaseAlways<FravaerContext>
{
protected override void Seed(FravaerContext context)
{
for (int i = 1; i <= 4; i++)
{
User chief = new User() {Id = i, Absences = new List<Absence>(), Email = $"chief{i}@chief.dk", FirstName = $"Chief{i}",LastName = $"Chiefsen{i}",Password = "admin",UserName = ""+i,Role = Role.DepartmentChief};
Department d = new Department() {Id = i, Users = new List<User>() { chief }, DepartmentChief = chief };
chief.Department = d;
context.Departments.Add(d);
}
base.Seed(context);
}
}
和我的实体 (AbstractEntity仅向实体类提供ID):
public class Department : AbstractEntity
{
public List<User> Users { get; set; }
public User DepartmentChief { get; set; }
}
public class User : AbstractEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public List<Absence> Absences { get; set; }
public Department Department { get; set; }
public Role Role { get; set; }
}
嗯,您遇到了所有这些错误,因为您已经在实体之间创建了循环所需的依赖关系,现在数据库不知道如何正确插入它们。
然后,您需要稍微放松一下模型,以便所需的属性之一变为可选,然后就可以正确地播种数据库了。
假设您在用户实体中将“部门”设置为可选。
目前,由于您没有在OnModelCreating方法上定义外键,因此让EF生成外键。
因此,首先将外键暴露给用户:
public class User : AbstractEntity
{
public int? DepartmentId { get; set; }
}
请注意,我已将其设置为可为空,因此我们现在可以将此关系定义为可选:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOptional(u => u.Department)
.WithMany(d => d.Users)
.HasForeignKey(x => x.DepartmentId)
.WillCascadeOnDelete(false);
}
确保在Department的构造函数上初始化Users属性,以便在尝试将用户添加到Department时不会出现NullReferenceException:
public Department()
{
Users = new List<User>();
}
创建一个新的迁移并更新您的数据库。 然后,您可以使用以下初始化程序:
public class DBInitializer : DropCreateDatabaseAlways<FravaerContext>
{
protected override void Seed(FravaerContext context)
{
//create the users first
//save the users in a list so later we can create the departments
var users = new List<User>();
for (var i = 1; i <= 4; i++)
{
var user = new User
{
Id = i,
Absences = new List<Absence>(),
Email = $"chief{i}@chief.dk",
FirstName = $"Chief{i}",
LastName = $"Chiefsen{i}",
Password = "admin",
UserName = "user" + i,
Role = Role.DepartmentChief
};
users.Add(user);
context.Users.Add(user);
}
//create one department for each user (with that user as the chief)
var departmentId = 1;
//save the departments so later we can seed them with users
var departments = new List<Department>();
foreach (var user in users)
{
var d = new Department
{
Id = departmentId++,
DepartmentChief = user
};
departments.Add(d);
context.Departments.Add(d);
}
//seeed the departments with users
foreach (var department in departments)
{
//add 5 users to each department
for (var i = 1; i < 5; i++)
{
var user = new User
{
Absences = new List<Absence>(),
Email = $"user{department.Id}{i}@user.dk",
FirstName = $"User{department.Id}{i}",
LastName = $"Username{department.Id}{i}",
Password = "user",
UserName = "" + department.Id + i,
Role = Role.DepartmentChief
};
department.Users.Add(user);
}
}
}
}
我在这里所做的是将播种任务分解为较小的部分,因此我首先创建主要用户(不包含部门),然后创建具有先前创建的用户的部门,最后创建每个部门的用户。
这种方法的优点是您可以完全控制创建的用户,部门和负责人的数量。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.