简体   繁体   English

如何在实体框架中循环创建和删除记录

[英]How do I create and delete records in Entity Framework in a loop

We have a postgres database to store Event objects and use Entity Framework as our ORM.我们有一个 postgres 数据库来存储Event对象并使用实体框架作为我们的 ORM。

In a background service, which runs periodically, we want to get all expired events, delete them from the Event table and move them to the EventArchive table.在定期运行的后台服务中,我们希望获取所有过期事件,将它们从Event表中删除并将它们移动到EventArchive表中。

We have a service class ExpiredEventService which retrieves all expired events and passes them to a repository class for deletion and creating EventArchive items.我们有一个服务 class ExpiredEventService检索所有过期事件并将它们传递到存储库 class 用于删除和创建EventArchive项目。

Through logging we have noticed that the expired events are indeed retrieved and that the code for deleting and creating archive item does not result in an exception.通过日志记录,我们注意到确实检索到了过期事件,并且删除和创建存档项的代码不会导致异常。

However the items are not deleted and no EventArchive items are created.但是,项目不会被删除,也不会创建EventArchive项目。

We use the following code to move these items to the archive:我们使用以下代码将这些项目移动到存档:

public async Task MoveEventsToArchive(IList<Event> events, CancellationToken cancellationToken)
{
    using (var dbContextTrans = _dbContext.Database.BeginTransactionAsync(IsolationLevel.ReadUncommitted, cancellationToken))
    {
        foreach(var event in events)
        {
            var archiveItem = new ArchiveEvent(event);
            archiveItem.Status = EventStatus.Archived;
            _dbContext.ArchiveEvents.Add(archiveItem);
            _dbContext.Events.Remove(event);
        }
        await _dbContext.SaveChangesAsync(cancellationToken);
    }
}

What is the correct way to do this?这样做的正确方法是什么?

You have to commit your transaction.你必须提交你的交易。 Also I suggest using AddRange and RemoveRange methods to improve your performance.我还建议使用 AddRange 和 RemoveRange 方法来提高性能。

using (var transaction = _dbContext.Database.BeginTransactionAsync())
{
  var archives = new List<ArchiveEvent>();
  foreach(var event in events)
  {
    var archiveItem = new ArchiveEvent(event);
    archiveItem.Status = EventStatus.Archived;
    archives.Add(archiveItem);              
  }
  _dbContext.ArchiveEvents.AddRange(archives);
  _dbContext.Events.RemoveRange(events);
  await _dbContext.SaveChangesAsync();
  await transaction.CommitAsync();
}

Note: If AddRange causes PK insert problems and you can change the model, add this in your PK:注意:如果 AddRange 导致 PK 插入问题并且您可以更改 model,请将其添加到您的 PK 中:

public class ArchiveEvent
{ 
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public long id { get; set; }
  //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM