使用AFTER INSERT触发器将实体框架插入表中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用AFTER INSERT触发器将实体框架插入表中相关的知识,希望对你有一定的参考价值。

我正在开发一个Web API和实体框架6,它在任何给定时间对Microsoft SQL Server表执行500个以下记录的“批量”插入。 DbContext.SaveChanges()方法将在几秒钟内将所有记录插入到表中,因此没有任何问题。但是,当调用该方法将相同数量的记录插入到同一个表中且附加了半广泛触发器时,该过程可能需要很长时间。触发器有一些调用表连接并插入到其他表中,然后删除新插入的记录。

我对表格或触发器没有太多控制权,所以我正在寻找有关如何提高性能的建议。我建议将触发器移动到存储过程并让触发器调用存储过程,但我不确定是否会获得任何收益。

编辑:据我所知,我的问题是通用的,我会发布我的一些代码,以防它有所帮助。 SQL不是我的,所以我会看到我实际发布的内容。

以下是我调用SaveChanges()的Web API方法的一部分:

string[] stringArray = results[0].Split(new[] { "
", "
", "
" }, StringSplitOptions.None);

var profileObjs = db.Set<T_ProfileStaging>();
foreach (var s in stringArray)
{

    string[] columns = s.Split(new[] {",", "	"}, StringSplitOptions.None);
    if (columns.Length == 6)
    {
        T_ProfileStaging profileObj = new T_ProfileStaging();

        profileObj.CompanyCode = columns[0];
        profileObj.SubmittedBy = columns[1];
        profileObj.VersionName = columns[2];
        profileObj.DMName = columns[3];
        profileObj.Zone = columns[4];
        profileObj.DMCode = columns[5];
        profileObj.ProfileName = columns[6];
        profileObj.Advertiser = columns[7];
        profileObj.OriginalInsertDate = columns[8];

        profileObjs.Add(profileObj);
    }
}

try
{
    db.SaveChanges();
    return Ok();
}
catch (Exception e)
{
    return Content(HttpStatusCode.BadRequest, "SQL Server Insert Exception");
}
答案

使用SaveChanges()加载时,EF将在单独的INSERT语句中发送每一行。因此,如果您有一个语句触发器,它将为每一行运行。

要解决这个问题,你需要

  • 使用来自客户端的批量加载API(而不是EF的SaveChanges())直接使用SqlBulkCopy,或者包装它的许多EF扩展之一。

要么

  • 配置EF以插入到不同的表中,然后将INSERT ... SELECT插入目标表

以上是关于使用AFTER INSERT触发器将实体框架插入表中的主要内容,如果未能解决你的问题,请参考以下文章

AFTER DELETE 触发器触发但不将记录插入审计表

SQLServer之创建DML AFTER INSERT触发器

在 AFTER INSERT 触发器中删除表

sql server 的after触发器之insert触发器实例

SQL Server“AFTER INSERT”触发器看不到刚刚插入的行

db2触发器after insert中怎么取得插入前的数据