【问题标题】:How to make entity framework insert entries in one trip to database如何使实体框架在一次访问数据库中插入条目
【发布时间】:2017-01-16 09:15:00
【问题描述】:

我有一个使用 EntityFramework 代码优先定义的一对多关系。类似于:包含 SmallEntitiesList(SmallEntity 列表)的 BigEntity。

每当我更新该对象的 SmallEntities 列表并执行 dbContext.SaveChanges() 时,我可以在 SQL 记录器中看到 Entity Framework 通过为每个项目往返数据库来插入这些项目 .

所以日志看起来像这样:

每个插入看起来像这样:

DECLARE
  updatedRowid ROWID;
BEGIN


INSERT INTO SOME_TABLE(...)
VALUES (...)

RETURNING ROWID INTO updatedRowid;
OPEN '' /* @outParameter */ FOR SELECT
     SOME_TABLE 
FROM SOME_TABLE 
WHERE ROWID = updatedRowid;
END;

有没有办法让实体框架表现出不同的行为,并让这些插入物为每个插入物访问数据库?

更新:已经尝试过 BulkInsert(不支持 Oracle DevArt,这是我正在使用的)。

【问题讨论】:

  • 请查看我的回答,希望对您有所帮助。我在我的项目中使用它。

标签: c# .net entity-framework ef-code-first


【解决方案1】:

如果您使用的是 EF(版本 6)6.1.3,那么您可以使用提供的 EntityFramework.BulkInsert 扩展来实现这一点。它将在单个调用中插入对象列表,这将极大地提高应用程序的性能。 形成更多信息,看看这个。

https://efbulkinsert.codeplex.com/

【讨论】:

  • 除非您修复它,否则这不适用于图形层次结构。它只会插入一层。您还需要小心批量插入选项,就好像您不小心一样,它可以绕过您身上的很多规则。
  • @DanielLorenz 对不起,我没明白你的意思。你能告诉我在哪里可以读到更多关于你所说的话。另外问题是为单个实体插入批量插入,我认为 BulkInsert 对此有好处。
  • "我有一个使用 EntityFramework 代码优先定义的一对多关系" 这意味着他同时保存了一个父实体及其子实体。您的批量插入解决方案只会自动插入父实体而不是子实体。因此,您必须手动遍历树,这可能会在未来引起问题。
  • @DanielLorenz 你对 BulkInsert 有什么问题吗?
  • 我认为你没有抓住重点。如果他只是在一行代码中使用 BulkInsert,它就不会插入他的子实体。此外,如果他不知道那些 BulkInsert 选项的作用,它可能会在插入时跳过验证规则。当我知道我只使用一级实体时,我倾向于直接使用内置的 Sql Bulk Copy。如果我使用多个级别,我会尽量避免同时插入多个父母和多个孩子,以避免巨大的延迟。
【解决方案2】:
foreach(var item in ListItems)
{
  context.Entry(item).State = System.Data.EntityState.Added;
  context.Add(item);
}

context.SaveChanges();

foreach (var item in objectList)
{
  context.YourObject.AddObject(item );
}

context.SaveChanges(SaveOptions.None);

研究 - BulkInsert();

【讨论】:

  • 您的两个解决方案都在做同样的事情,结果没有变化,每个实体对数据库的访问次数相同。
  • 或者只使用存储过程:)
【解决方案3】:

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

这个库支持所有主要的供应商,包括:

  • Oracle DevArt
  • Oracle 数据访问
  • Oracle DataAccessManaged

此库允许您执行场景所需的所有批量操作:

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

例子

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    相关资源
    最近更新 更多