2016-11-30 3 views
0

имейте проблемы посев и создание базы данных, соответствующей моим потребностям. У меня есть 2 объекта; Пользователь и отдел. Пользователь требует наличия отдела, а отдел может иметь много пользователей, но в то же время Департаменту требуется, чтобы один пользователь был его департаментом. Я могу понять, как я могу настроить это, каждая попытка привела к исключениям различного рода.код посева первая текущая база данных api EF кодовые ошибки


Вот мой контекст:

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 предоставляет только идентификатор сущностей-классов):

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

} 
+0

Почему вы не вызвали 'SaveChanges' в методе' Seed'? –

+0

Мне не нужно. Ive теперь это работает, и я никогда не использую save changes :) – Bille

ответ

0

Ну, вы испытываете все эти ошибки, потому что вы создали круговые требуемые зависимости между вашими сущностями, и теперь база данных не знает, как чтобы вставить их правильно.

Вам понадобится немного потерять свою модель, чтобы одно из необходимых свойств стало необязательным, и вы сможете правильно засеять свою базу данных.

Предположим, вы установили Департамент как необязательный в свой пользовательский объект.

В настоящий момент вы позволяете EF генерировать внешний ключ, поскольку вы не определяете его по методу OnModelCreating.

Так начните, подвергая свой внешний ключ на ваш пользователь:

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

Убедитесь, что вы инициализируйте свойство своих пользователей на конструкторе Департамента, чтобы вы не получили исключение 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); 
      } 
     } 
    } 
} 

Что я сделал здесь разложить высев задачу на более мелкие куски, так что я сначала создать главные пользователь (без отдела), а затем создать отделы с ранее созданных пользователей и, наконец, пользователей для каждого отдела.

Преимущество этого метода в том, что у вас есть полный контроль над тем, сколько пользователей, отделов и начальников вы создаете.

Надеюсь, это поможет!

Смежные вопросы