原因:
数据库中的两个表是主从表关系,但是没有建外键,而表的id用的是数据库的自增整数,导致在使用EF导入主从表数据时,需要先保存主表数据,取到
主表的自增id后才能插入从表数据,这样循环之下,数据插入速度非常慢。
经过查询得知:
即使在数据库中没有建立外键关系,也可以在EF中通过关系建议主从表关系,从而达到批量导入主从表数据的目的。
具体实现:
首先model中需要添加主从表的关系属性
主表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[Table("DataHubEmployee")] public partial class DataHubEmployee : SecuredEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int pkDataHubEmployee { get; set; } public int fkDataHubBatch { get; set; } public int? OriginalBatchId { get; set; } public int EmployeeId { get; set; } public string ClientCode { get; set; } public virtual ICollection<DataHubDependant> DataHubDependants { get; set; } }
从表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[Table("DataHubDependant")] public partial class DataHubDependant : SecuredEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int pkDataHubDependant { get; set; } public int? OriginalBatchId { get; set; } public string ClientCode { get; set; } public int fkDataHubEmployee { get; set; } public string EmployeeId { get; set; } public string FullName { get; set; } public virtual DataHubEmployee DataHubEmployee { get; set; } }
然后EF的DbContext中的OnModelCreating对实体的外键关联进行注册
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Properties<decimal>().Configure(c => c.HasPrecision(18, 6)); //add model mapping for auto process modelBuilder.Entity<DataHubDependant>() .HasRequired(d => d.DataHubEmployee) .WithMany(e => e.DataHubDependants) .HasForeignKey(d => d.fkDataHubEmployee); modelBuilder.Entity<DependantChangeLog>() .HasRequired(d => d.EmployeeChangeLog) .WithMany(e => e.DependantChangeLogs) .HasForeignKey(d => d.fkEmployeeChangeLog); //close auto migration Database.SetInitializer<ClientDbContext>(null); base.OnModelCreating(modelBuilder); }
说明:这里可以通过.HasForeignKey(d => d.fkDataHubEmployee);来指定从表中的哪个字段是外键。如果不指定,EF会自动生产一个包含外键的新列。
批量插入数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
foreach (var dataHubEmployeeDTO in dataHubEmployeeDtoList) { if (batchType == "MonthlyData" && dataHubEmployeeDTO.Status.ToUpper() == "Terminated".ToUpper()) { continue; } DataHubEmployee dataHubEmployee = new DataHubEmployee { EmployeeId = dataHubEmployeeDTO.EmployeeId, fkDataHubBatch = dataHubBatch.pkDataHubBatch, OriginalBatchId = batchId, ClientCode = dataHubEmployeeDTO.ClientCode, DataHubDependants = new List<DataHubDependant>() }; //插入重表数据 //获取当前批员工列表 foreach (var dependant in dataHubEmployeeDTO.DependantList) { var dataHubDependant = new DataHubDependant { OriginalBatchId = batchId, ClientCode = dataHubEmployeeDTO.ClientCode, fkDataHubEmployee = dataHubEmployee.pkDataHubEmployee, EmployeeId = dataHubEmployeeDTO.ID, FullName = dependant.FullName, Identification = dependant.Identification, BirthDate = dependant.BirthDate, Gender = dependant.Gender, Nationality = dependant.Nationality, }; dataHubEmployee.DataHubDependants.Add(dataHubDependant); } clientDbContext.DataHubEmployee.Add(dataHubEmployee); } clientDbContext.SaveChanges();
这样就可以在批量插入数据的时候,自动填充主表的自增ID到从表。