【问题标题】:BulkInsert: The INSERT statement conflicted with the FOREIGN KEY constraintBulkInsert:INSERT 语句与 FOREIGN KEY 约束冲突
【发布时间】:2016-12-21 08:27:10
【问题描述】:

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

我需要向数据库添加一个包含 500 步的新项目。如果我使用简单的 EntityFramework - 我没有问题,但就我在 SQL Profiler 中有 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 方法中,我收到一个错误:“INSERT 语句与 FOREIGN KEY 约束冲突

FK_dbo.StepImplementation_dbo.Project_Project_Id"。冲突 发生在数据库“RelimeDB”、表“dbo.Project”、“Id”列中。这 语句已终止。

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

【问题讨论】:

  • 你的StepImplementations 类可能有一个“ProjectId”属性,尝试设置它而不是/以及Project 属性。我猜BulkInsert 不会查看子对象。
  • 另外,你真的应该在继续之前检查checkProjectExists是否为空,或者,如果你知道它会一直存在,使用First或Single而不是FirstOrDefault
  • 在我的 StepImplementation 类中 Project 是虚拟的:public virtual Project Project { get; set; } 在这种情况下我无法设置 Project_Id,我收到错误消息。

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


【解决方案1】:

小心,

EntityFramework.BulkInsert 是一个非常好的库,适用于一些基本场景,但无法支持更复杂的场景。

例如,库不支持:

  • 复杂关联
  • 复杂类型
  • 导航属性(如您的情况)
  • TPC
  • TPT
  • 输出标识值

还有一些其他的东西

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

目前支持批量插入的三大类库

见:Entity Framework Bulk Insert Library

免责声明:我是Entity Framework Extensions的所有者

这个库不是免费的,但支持您执行 BulkOperations 可能需要的一切

  • 批量保存更改
  • 批量插入
  • 批量更新
  • 批量删除
  • 批量合并

例子:

// 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;
});

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多