实体框架将对象从一个上下文传递到另一个上下文

jkr*_*r01 12 c# multithreading entity-framework

我是实体框架的新手,所以请耐心等待.

我有一个程序,我想从表中选择多个记录并将其存储在队列中:

private Queue<RecordsToProcess> getRecordsToProcess()
{
    Queue<RecordsToProcess> results = new Queue<RecordsToProcess>();
    using (MyEntity context = new MyEntity())
    {
        var query = from v in context.RecordsToProcess
                            where v.Processed == false
                            select v;

        foreach (RecordsToProcess record in query)
        {
            results.Enqueue(record);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我启动了多个工作线程.每个工作线程获取队列中的一个项目,对其进行处理,然后将其保存到数据库中.

private void processWorkerThread(object stateInfo)
{
    while (workQueue.Count > 0)
    {
        RecordToProcess record = new RecordToProcess;
        lock(workQueue)
        {
            if (workQueue.Count > 0)
                RecordToProcess = workQueue.Dequeue();
            else
                break;
        }

        //Do the record processing here

        //How do I save that record here???
    }
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,要将更改保存回数据库,您只需调用context.SaveChanges()但我不能在这种情况下这样做吗?

任何帮助表示赞赏.

谢谢!

khe*_*ang 10

由于您MyEntity在第一种方法中处理上下文(通过将其包装在using语句中),因此排队的实体将处于"分离"状态.这意味着,除其他外,将不会跟踪对实体所做的更改,并且您将无法延迟加载导航属性.

将这些实体出列,将它们"附加"到不同的上下文,更新它们然后调用SaveChanges以保持更改是完全正常的.

您可以阅读有关附加和分离对象以及添加/附加和实体状态的信息

  • 我仍然认为将实体明确加载为未跟踪是更好的方法。意图更清晰,不依赖于事先处理的上下文。事实上,在提供的代码中,不能保证在将 item 交给工作线程之前已经处理了上下文。加载未跟踪的实体也意味着加载跟踪的实体只是为了立即分离它们没有额外的性能损失。 (2认同)