.net c#调用多个SaveChanges()

Calling multiple SaveChanges()
2020-11-21
  •  译文(汉语)
  •  原文(英语)

我正在尝试在一个数据库表上异步工作并提交对它的更改,但是它并没有按照我的意愿工作.

这是我在对象构造函数上运行任务的第一个方法,该任务不忙于等待集合中的一些新对象并逐个处理它们.(从表中删除)

    private static BlockingCollection<QueuedLog> queue = new BlockingCollection<QueuedLog>();

    private void Start()
    {
        Task.Run(() =>
        {
            while (taskQueueActive)
            {
                using (var scope = new TransactionScope())
                {
                    QueuedLog log = queueLogs.Take();

                    // I process it somehow here

                    uow.QueuedLogRepository.Delete(log);

                    if (queueLogs.Count == 0)
                        uow.Save();

                    scope.Complete();
                }
            }
        });
    }

这是将对象提供给数据库的第二种方法.(添加到表中)

        using (var scope = new TransactionScope())
        {
            uow.MonitoringIdRepository.Add(logs.First(), out id);
            uow.QueuedLogRepository.Add(logs, id);
            uow.Save();

            scope.Complete();
        }

两种方法都使用具有所需存储库的相同UnitOfWork对象.

在运行应用程序之后,当队列任务正在运行时-当我向第二种方法发送新对象时,出现以下错误:

EntityFramework.dll中发生类型为'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException'的异常,但未在用户代码中处理.附加信息:存储更新,插入或删除语句影响了意外的行数(0).自加载实体以来,实体可能已被修改或删除.刷新ObjectStateManager条目.

问题是:如何摆脱这种例外?或者我该怎么做?我已经尝试过新的EF 6.0 BeginTransaction方法,但是它对我也不起作用(或者也许我用错了它们).

速聊1:
您没有使用本地Async调用的原因吗?
速聊2:
您是否在多个线程上使用相同的数据上下文?
速聊3:
其实...是的,我在多个线程上使用了相同的上下文.这就是为什么我会收到所有这些错误的原因吗?
解决过程1

您不应该在多个线程之间共享上下文对象.您发布的错误消息实质上表明上下文对象意识到实体已被修改.

尝试为每个线程使用单独的上下文对象:实体框架线程安全

速聊1:
所以我该怎么做?当我为两个线程都创建上下文并且仍然在单独的上下文上处理ADD / DELETE操作时,它将起作用吗?可以说这是一个反问的问题-当我回到家时,我会检查一下.非常感谢!

I'm trying to work asynchronously on one database table and commit changes to it but it doesn't work as I would like it to.

This is my first method where I'm running a task on object constructor which is non-busy waiting for some new objects in the collection and processing them one by one. (Deleting from the table)

    private static BlockingCollection<QueuedLog> queue = new BlockingCollection<QueuedLog>();

    private void Start()
    {
        Task.Run(() =>
        {
            while (taskQueueActive)
            {
                using (var scope = new TransactionScope())
                {
                    QueuedLog log = queueLogs.Take();

                    // I process it somehow here

                    uow.QueuedLogRepository.Delete(log);

                    if (queueLogs.Count == 0)
                        uow.Save();

                    scope.Complete();
                }
            }
        });
    }

And here's the second method which is providing the objects to the database. (Adding to the table)

        using (var scope = new TransactionScope())
        {
            uow.MonitoringIdRepository.Add(logs.First(), out id);
            uow.QueuedLogRepository.Add(logs, id);
            uow.Save();

            scope.Complete();
        }

Both methods are using the same UnitOfWork object with needed repositories.

After I run the app and while the queue task is running - when I'm sending new objects to the second method, I'm getting the error below:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException' occurred in EntityFramework.dll but was not handled in user code. Additional information: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

The question is: how to get rid of this exception? Or how can I do it in some other way? I've tried already the new EF 6.0 BeginTransaction method but it also didn't work for me (or maybe i used them wrong).

Talk1:
Any reaons you aren't using the native Async calls?
Talk2:
Are you using the same data context on multiple threads?
Talk3:
Actually... Yes, I'm using the same context on multiple threads. Is this the reason why I'm getting all those errors?
Solutions1

You shouldn't be sharing your context objects across multiple threads. The error message you posted is essentially stating that the context object realizes entities have been modified.

Try using a separate context object for each thread: Entity Framework Thread Safety

Talk1:
So what should I do? When I will create context for both threads and still process ADD/DELETE actions but on separate contexts, will it work? Lets say this is a rhetorical question - I'll check this out when I'll come back home. Thanks a lot!
转载于:https://stackoverflow.com/questions/28333277/calling-multiple-savechanges

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入