Entity Framework Core中批量插入考勤时自动赋值主表Id到子表
如何将自动生成的BulkAttendance.Id赋值给关联的BulkAttendanceDetail.AttendanceId?
我在提交员工考勤数据时遇到问题:BulkAttendance模型的Id字段是数据库自动生成的(标记了[DatabaseGenerated(DatabaseGeneratedOption.Identity)]),需要把这个自动生成的Id值赋值给关联的BulkAttendanceDetail模型的AttendanceId字段。
模型类定义
public class BulkAttendance { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public int EmployeeCategoryId { get; set; } public int EmployeeLabourGroup { get; set; } public int CompanyId { get; set; } public int BranchId { get; set; } public int FinancialYearId { get; set;} public int ApprovalStatus { get; set; } public int ApprovalLevel { get; set; } public DateTime? ApprovedDate { get; set; } public DateTime FromDate { get; set; } public DateTime ToDate { get; set; } public int UserId { get; set; } public int CurrencyPrecision { get; set; } public List<BulkAttendaceDetail> AttendanceDetail { get; set; } } public class BulkAttendaceDetail { public string AttendanceId { get; set; } public string FullName { get; set; } public DateTime DateWorked { get; set; } public DateTime LoginTime { get; set; } public DateTime LogoutTime { get; set; } public int Employeeid { get; set; } public int ProjectId { get; set; } public string ProjectName { get; set; } public int Category { get; set; } public int WorkId { get; set; } public decimal Amount { get; set; } public int Work { get; set; } public decimal OverTime { get; set; } public decimal OverTimeAmount { get; set; } public string WorkCategoryName { get; set; } public string WorkShortName { get; set; } public decimal OvertimeRate { get; set; } public DateTime TimeIn { get; set; } public DateTime TimeOut { get; set; } public decimal SalaryAmount { get; set; } }
当前插入数据的代码
public async Task BulkAttendanceEntry(List<BulkAttendance> attendances) { try { foreach (var attendance in attendances) { await _bulkAttendanceContext.tbl_AttendanceMaster.AddAsync(attendance); if (attendance.AttendanceDetail != null && attendance.AttendanceDetail.Any()) { foreach(var attendanceDetail in attendance.AttendanceDetail) { } } } } catch(Exception) { throw; } }
解决方案
核心问题是:调用AddAsync只是将实体加入EF Core上下文跟踪,此时数据库还未生成Id值,必须先调用SaveChangesAsync将BulkAttendance写入数据库,才能获取到自动生成的Id,之后再给关联的明细赋值并保存。
修改后的代码如下:
public async Task BulkAttendanceEntry(List<BulkAttendance> attendances) { try { foreach (var attendance in attendances) { // 将主实体添加到上下文 await _bulkAttendanceContext.tbl_AttendanceMaster.AddAsync(attendance); // 保存主实体以获取自动生成的Id await _bulkAttendanceContext.SaveChangesAsync(); if (attendance.AttendanceDetail != null && attendance.AttendanceDetail.Any()) { foreach(var attendanceDetail in attendance.AttendanceDetail) { // 将主实体Id转为字符串赋值给明细的AttendanceId attendanceDetail.AttendanceId = attendance.Id.ToString(); // 将明细实体加入上下文 _bulkAttendanceContext.tbl_AttendanceDetail.Add(attendanceDetail); } // 保存明细数据 await _bulkAttendanceContext.SaveChangesAsync(); } } } catch(Exception) { throw; } }
补充说明
- 请将代码中的
tbl_AttendanceDetail替换为你实际的BulkAttendaceDetail对应的DbSet名称。 - 也可以选择统一保存所有数据,先完成主实体的保存和明细的赋值,最后一次性提交:
public async Task BulkAttendanceEntry(List<BulkAttendance> attendances) { try { foreach (var attendance in attendances) { await _bulkAttendanceContext.tbl_AttendanceMaster.AddAsync(attendance); await _bulkAttendanceContext.SaveChangesAsync(); if (attendance.AttendanceDetail != null && attendance.AttendanceDetail.Any()) { foreach(var attendanceDetail in attendance.AttendanceDetail) { attendanceDetail.AttendanceId = attendance.Id.ToString(); _bulkAttendanceContext.tbl_AttendanceDetail.Add(attendanceDetail); } } } // 统一提交所有明细数据 await _bulkAttendanceContext.SaveChangesAsync(); } catch(Exception) { throw; } }
内容的提问来源于stack exchange,提问作者user18243088
相关产品推荐
相关产品推荐

