【发布时间】:2021-03-25 14:13:22
【问题描述】:
我想使用 EF Core 的 TPT 功能,我想将它与 Identity 集成,但我在添加到数据库时遇到了一些问题。
public class ApplicationUser : IdentityUser<Guid>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string NationalCode { get; set; }
public DateTime BirthDate { get; set; }
public Gender Gender { get; set; }
}
public class Student : ApplicationUser
{
public string FatherName { get; set; }
public string PlaceOfBirth { get; set; }
public string Address { get; set; }
public string HomePhoneNumber { get; set; }
}
public class Teacher : ApplicationUser
{
public string FieldOfStudy { get; set; }
public AcademicDegree AcademicDegree{ get; set; }
public int YearsOfExperience { get; set; }
}
这是我的数据库上下文类
public class SchoolMgmtContext : IdentityDbContext<ApplicationUser,ApplicationRole,Guid>
{
public SchoolMgmtContext(DbContextOptions<SchoolMgmtContext> dbContextOptions)
:base(dbContextOptions)
{
}
public DbSet<Teacher> Teachers { get; set; }
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ApplicationUser>().ToTable("Users");
builder.Entity<Student>().ToTable("Students");
builder.Entity<Teacher>().ToTable("Teachers");
builder.Entity<ApplicationRole>().ToTable("Roles");
}
}
一切正常。
但我不知道如何插入新教师或新学生。
例如,这是添加新教师的代码。
public IActionResult CreateTeacher()
{
ViewBag.Users = new SelectList(_db.Users.Select(u => new { u.Id, FullName = u.FirstName + " " + u.LastName }), "Id", "FullName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateTeacher(TeacherCreationDto teacherCreationDto)
{
if (ModelState.IsValid)
{
var newTeacher = new Teacher()
{
AcademicDegree = teacherCreationDto.AcademicDegree,
FieldOfStudy = teacherCreationDto.FieldOfStudy,
YearsOfExperience = teacherCreationDto.YearsOfExperience,
Id= teacherCreationDto.UserId
};
// _db.Teachers.Update(newTeacher); // here I tested Attach - Add - Update, but none of this work.
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
else
{
ViewBag.Users = new SelectList(_db.Users.Select(u => new { u.Id, FullName = u.FirstName + " " + u.LastName }), "Id", "FullName");
return View(teacherCreationDto);
}
}
我应该如何添加新的学生或教师?谢谢,
【问题讨论】:
-
您添加新 TPT 记录的方式与添加新 TPH 或常规记录的方式相同 - 通过使用某些
Add方法,例如对于新的Teacher,其中任何一个都应该这样做-_db.Add(newTeacher)、_db.Users.Add(newTeacher)、_db.Teachers.Add(newTeacher)。你是什么意思“没有这个工作”?您是否遇到异常或? -
@IvanStoev 感谢您的回答,但这些方法都不起作用,是的,我有 2 个例外,第一个是关于 DbConcurreny,第二个是关于无法插入重复的主键。
-
这是因为这里
Id= teacherCreationDto.UserId您正在将现有 ID 分配给新用户(教师)。使用Id = Guid.NewGuid()或者不分配它,让 EFC 自动生成它。 -
@IvanStoev 为什么在 Microsoft docs 或 StackOverflow 中没有关于带有 TPT 的 EF Core 5 中的 CRUD 的代码?
-
嗯,看来你误解了继承的概念。教师是用户,学生也是如此。您不会创建单独的用户并将其“连接”到教师或学生 - 您创建的新教师也是新用户。 TPT 和 TPH 只是在数据库中存储此类继承数据的不同方式。如果您想将对象“连接”到 User,则不应使用继承,而应使用 FK 关系。
标签: asp.net-core entity-framework-core table-per-type ef-core-5.0