Я пытаюсь сделать проект приложения для отпуска, чтобы пройти курс обучения в колледже. Используя последние версии .net(8) и Entity Framework, я уже создал сущности, перечисления, базовые интерфейсы и т. д. В контроллере пока есть только метод create для класса person. Но у меня проблема с заполнением данных. Ниже приведены фрагменты кода из dbcontext, а также классы заполнения данных и скриншот из базы данных. Я пробовал разные варианты посева, но всегда где-то выдает ошибку.
Сообщение об ошибке:
Microsoft.EntityFrameworkCore.DbUpdateException: «Произошла ошибка при сохранении изменений сущности. Подробности смотрите во внутреннем исключении. SqlException: инструкция INSERT конфликтует с ограничением FOREIGN KEY «FK_People_Teams_Id». Конфликт произошел в базе данных «HolidayAppDb», таблица «dbo.Teams», столбец «TeamID».
Раздатчик людей, проблема возникает при сохранении от первого лица:
public async Task Seed()
{
if (await _dbContext.Database.CanConnectAsync())
{
if (!_dbContext.HolidayRequests.Any())
{
var teamExists = await _dbContext.Teams.AnyAsync();
if (!teamExists)
{
throw new Exception("The team does not exist.");
}
var approvedByFirstLeader = _dbContext.People.OrderBy(p => p.Id).First();
var approvedBySecondLeader = _dbContext.People.OrderByDescending(p => p.Id).First();
var firstPerson = new Person()
{
Id = Guid.NewGuid(),
FirstName = "Jacek",
LastName = "Magiera",
DateOfBirth = new DateTime(1980, 1, 1),
Position = "Developer",
StartDate = new DateTime(2020, 1, 1),
IsFullTime = true,
ContactDetails = new()
{ City = "Warsaw", Street = "Miodowa", Email = "[email protected]", PhoneNumber = "+48878453875", PostalCode = "42-290" },
HolidayTimeRemain = 10,
TeamId = _dbContext.Teams.OrderBy(t => t.TeamID).First().TeamID,
Team = _dbContext.Teams.OrderBy(t => t.TeamID).First()
};
_dbContext.People.Add(firstPerson);
await _dbContext.SaveChangesAsync();
firstPerson.HolidayRequests = new List<HolidayRequest>()
{
new HolidayRequest()
{
Description = "Winter Vacation",
CreatedAt = new DateTime(2022, 1, 1),
StartDate = new DateTime(2022, 1, 10),
EndDate = new DateTime(2022, 1, 20),
Status = HolidayRequestStatusEnum.Completed,
Type = HolidayTypeEnum.PaidLeave,
IsApproved = true,
ApprovedDate = new DateTime(2021, 12, 1),
ApprovedBy = approvedByFirstLeader
}
};
_dbContext.HolidayRequests.Add(firstPerson.HolidayRequests.First());
var secondPerson = new Person()
{
Id = Guid.NewGuid(),
FirstName = "Adam",
LastName = "Nowak",
DateOfBirth = new DateTime(1985, 1, 1),
Position = "Developer",
StartDate = new DateTime(2021, 1, 1),
IsFullTime = true,
ContactDetails = new()
{ City = "Krakow", Street = "Zielona", Email = "[email protected]", PhoneNumber = "+48888453875", PostalCode = "30-300" },
HolidayTimeRemain = 15,
TeamId = _dbContext.Teams.OrderByDescending(t => t.TeamID).First().TeamID,
Team = _dbContext.Teams.OrderByDescending(t => t.TeamID).First()
};
_dbContext.People.Add(secondPerson);
await _dbContext.SaveChangesAsync();
secondPerson.HolidayRequests = new List<HolidayRequest>()
{
new HolidayRequest()
{
Description = "Summer Vacation",
CreatedAt = new DateTime(2022, 1, 1),
StartDate = new DateTime(2022, 7, 10),
EndDate = new DateTime(2022, 7, 20),
Status = HolidayRequestStatusEnum.Completed,
Type = HolidayTypeEnum.PaidLeave,
IsApproved = true,
ApprovedDate = new DateTime(2021, 12, 1),
ApprovedBy = approvedBySecondLeader
}
};
_dbContext.HolidayRequests.Add(secondPerson.HolidayRequests.First());
await _dbContext.SaveChangesAsync();
}
}
}
Сеятель команды:
public async Task Seed()
{
if (await _dbContext.Database.CanConnectAsync())
{
if (!_dbContext.Teams.Any())
{
var firstTeam = new Team() { Name = "Team 1", Description = "First team", IsActive = true, Department = "IT" };
var secondTeam = new Team() { Name = "Team 2", Description = "Second team", IsActive = true, Department = "IT" };
_dbContext.Teams.Add(firstTeam);
_dbContext.Teams.Add(secondTeam);
await _dbContext.SaveChangesAsync();
firstTeam.TeamLeader = new Person()
{
FirstName = "Jan",
LastName = "Kowalski",
DateOfBirth = new DateTime(1975, 1, 1),
Position = "Team Leader",
StartDate = new DateTime(2019, 1, 1),
IsFullTime = true,
ContactDetails = new()
{ City = "Czestochowa", Street = "Miodowa", Email = "[email protected]", PhoneNumber = "+48522456675", PostalCode = "42-200" },
HolidayTimeRemain = 5,
TeamId = firstTeam.TeamID
};
secondTeam.TeamLeader = new Person()
{
FirstName = "Anna",
LastName = "Kowalska",
DateOfBirth = new DateTime(1980, 1, 1),
Position = "Team Leader",
StartDate = new DateTime(2020, 1, 1),
IsFullTime = true,
ContactDetails = new()
{ City = "Warsaw", Street = "Czerwona", Email = "[email protected]", PhoneNumber = "+48555456675", PostalCode = "00-100" },
HolidayTimeRemain = 14,
TeamId = secondTeam.TeamID
};
_dbContext.Teams.Update(firstTeam);
_dbContext.Teams.Update(secondTeam);
await _dbContext.SaveChangesAsync();
}
}
}
класс dbcontext:
public HolidayAppDbContext(DbContextOptions<HolidayAppDbContext> options) : base(options)
{
}
public DbSet<Person> People { get; set; }
public DbSet<HolidayRequest> HolidayRequests { get; set; }
public DbSet<Team> Teams { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region Person
modelBuilder.Entity<Person>(eb =>
{
eb.Property(p => p.Id).ValueGeneratedOnAdd();
eb.Property(p => p.FirstName).IsRequired().HasMaxLength(50);
eb.Property(p => p.LastName).IsRequired().HasMaxLength(50);
eb.Property(p => p.HolidayTimeRemain).IsRequired();
eb.Property(p => p.DateOfBirth).IsRequired();
eb.Property(p => p.Position).IsRequired().HasMaxLength(50);
eb.Property(p => p.StartDate).IsRequired();
eb.Property(p => p.IsFullTime).IsRequired();
eb.HasOne(p => p.Team).WithMany(t => t.Persons).HasForeignKey(p => p.TeamId).OnDelete(DeleteBehavior.Restrict).IsRequired();
eb.HasMany(h => h.HolidayRequests).WithOne(p => p.Person).HasForeignKey(p => p.PersonId);
eb.OwnsOne(c => c.ContactDetails);
});
#endregion
#region HolidayRequest
modelBuilder.Entity<HolidayRequest>(eb =>
{
eb.Property(hr => hr.Description).IsRequired().HasMaxLength(1000);
eb.Property(hr => hr.StartDate).IsRequired();
eb.Property(hr => hr.EndDate).IsRequired();
eb.Property(hr => hr.Status).IsRequired();
eb.Property(hr => hr.Type).IsRequired();
eb.Property(hr => hr.IsApproved).IsRequired();
eb.Property(hr => hr.CreatedAt).IsRequired();
eb.Property(hr => hr.UpdatedAt).IsRequired();
eb.HasOne(hr => hr.ApprovedBy).WithMany().HasForeignKey(hr => hr.ApprovedById);
});
#endregion
#region Team
modelBuilder.Entity<Team>(eb =>
{
eb.Property(t => t.Name).IsRequired().HasMaxLength(50);
eb.Property(t => t.Description).IsRequired().HasMaxLength(1000);
eb.Property(t => t.IsActive).IsRequired();
eb.Property(t => t.Department).IsRequired().HasMaxLength(50);
eb.Property(t => t.CreatedDate).IsRequired();
eb.Property(t => t.ModifiedDate);
eb.HasOne(t => t.TeamLeader).WithOne().HasForeignKey<Person>(p => p.Id).IsRequired();
eb.HasMany(t => t.Persons).WithOne(p => p.Team).HasForeignKey(p => p.TeamId).IsRequired();
});
#endregion
}
Таблица персон
Таблица команд
PS: И почему мне не хватает ссылки на лидера группы в таблице команды? Есть идеи? Я что-то пропустил?
Да, я думаю, что делаю это правильно. var scope = app.Services.CreateScope(); var teamSeeder = scope.ServiceProvider.GetRequiredService<TeamSeeder>(); var personSeeder = scope.ServiceProvider.GetRequiredService<PersonSeeder>(); await teamSeeder.Seed(); await personSeeder.Seed(); Но я заметил, что идентификатор команды точно такой же, как идентификатор человека..
Заполнение после builder.Build(); и перед настройкой конвейера HTTP-запросов, перенаправления https и т. д.
Откуда контекст, он одинаков в обоих сидах? Выполняется ли у вас транзакция, если да, то на каком уровне изоляции?





Я не совсем знаком с беглым подходом (мы используем атрибуты модели). Но, судя по всему, вам не хватает определения столбца Id вашей команды.
Что-то вроде этого: eb.Property(t => t.Id).ValueGeneratedOnAdd(); (как в случае с сущностью «Люди»)
Благодаря этому EF будет знать, что нужно получить идентификатор из базы данных после вставки. В результате firstTeam.Id и secondTeam.Id в настоящее время не установлены, поскольку вы их не установили, и EF не знает, как их получить автоматически.
Я предполагаю, что вы устанавливаете свойство TeamLeader для команд, но не устанавливаете свойство TeamLeaderId для команд.
Стандартный способ сделать это — использовать свойство TeamLeaderId Guid и свойство TeamLeader Object, которое большую часть времени является виртуальным. Стандартным способом, если вы зададите только свойство Object, ничего не произойдет, поскольку в базе данных для него нет поля.
Задайте для свойства TeamLeaderId значение идентификатора человека. Но если у вас есть автоматически сгенерированные идентификаторы, то вам нужно сначала создать людей, вызвать сохранение изменений и получить их из базы данных, после чего вы можете обновить руководителей команд.
Где и в каком порядке вы запускаете эти
Seedметоды и правильно ли их ожидаете?