BulkInsert:INSERT语句与FOREIGN KEY约束冲突

时间:2016-12-21 08:27:10

标签: c# sql-server entity-framework bulkinsert

我有2个实体:Project和StepImplementation。 StepImplementation对Project表有一个FK。 Tables schema

我需要向数据库添加一个包含500个步骤的新项目。如果我使用一个简单的EntityFramework - 我没有问题,但据我在SQL事件探查器中有500个步骤,我观察500个插入。因此,我尝试使用EntityFramework.BulkInsert添加一个包含大量步骤的新项目。

public Project CreateProjectCopy(Project project)
{
    var newProject = this.repositoryScope.Projects.Value.Add(new Project()
    {
        Name = project.Name,
        BddFrameworkType = project.BddFrameworkType,
        Domain = project.Domain,
        IsActive = project.IsActive,
        IsPrivate = project.IsPrivate,
        ProjectKey = this.GenerateProjectKey(),
        SavingMode = project.SavingMode
    });

    this.repositoryScope.Projects.Value.SaveChanges();

    var checkProjectExists = this.repositoryScope.Projects.Value.GetFirstOrDefault(x => x.Id == newProject.Id);
    var steps = project.StepImplementations.Select(s => new StepImplementation()
    {
        DocComment = s.DocComment,
        StepImplementationText = s.StepImplementationText,
        Project = checkProjectExists
    }).ToList();
    this.repositoryScope.StepImplementations.Value.AddRange(steps);
    this.repositoryScope.StepImplementations.Value.SaveChanges();

    newProject.Branches = this.treeManager.CopyAll(project);

    return newProject;
}

public virtual void AddRange(List<T> entities)
{
    this.context.BulkInsert(entities, new BulkInsertOptions { SqlBulkCopyOptions = SqlBulkCopyOptions.CheckConstraints, BatchSize = entities.Count() });
}   

在AddRange方法上,我收到一个错误:&#34; INSERT语句与FOREIGN KEY约束冲突

  

FK_dbo.StepImplementation_dbo.Project_Project_Id&#34 ;.冲突   发生在数据库&#34; RelimeDB&#34;,table&#34; dbo.Project&#34;,column&#39; Id&#39;。该   声明已被终止。

但我故意添加了checkProjectExists变量来检查项目是否存在于数据库中。在addRange方法之前,我通过Sql Manager Studio检查新添加的项目并且它可用。那么为什么BulkInsert无法添加步骤,如果纯EntityFramework可以?

1 个答案:

答案 0 :(得分:1)

小心,

对于某些基本场景,

EntityFramework.BulkInsert是一个非常好的库,但却无法支持更复杂的场景。

例如,库支持:

  • 复杂协会
  • 复杂类型
  • 导航属性(与您的情况类似)
  • TPC
  • TPT
  • 输出标识值

以及其他一些东西

在您的情况下,它可能不支持导航属性并尝试插入带有NULL值的Project_Id列,或者它不是insert语句的一部分(因此使用默认值= Null)

目前有三个主要的图书馆支持批量插入

请参阅:Entity Framework Bulk Insert Library

免责声明:我是Entity Framework Extensions

的所有者

此库免费,但支持执行BulkOperations所需的一切

  • BulkSaveChanges
  • BulkInsert
  • BulkUpdate
  • BulkDelete
  • BulkMerge

示例:

// Easy to use
context.BulkSaveChanges();

// Easy to customize
context.BulkSaveChanges(bulk => bulk.BatchSize = 100);

// Perform Bulk Operations
context.BulkDelete(customers);
context.BulkInsert(customers);
context.BulkUpdate(customers);

// Customize Primary Key
context.BulkMerge(customers, operation => {
   operation.ColumnPrimaryKeyExpression = 
        customer => customer.Code;
});