实体框架的SaveChanges()与SaveChangesAsync()和find()与FindAsync() [英] Entity Framework SaveChanges() vs. SaveChangesAsync() and Find() vs. FindAsync()

查看:443
本文介绍了实体框架的SaveChanges()与SaveChangesAsync()和find()与FindAsync()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找2对之间的分歧之上,但还没有找到它清楚解释,以及何时使用一种或另一种的任何物品。

I have been searching for the differences between 2 pairs above but haven't found any articles explaining clearly about it as well as when to use one or another.

那么究竟是什么的SaveChanges() SaveChangesAsync()?结果
之间<之间的差异code>查找()和 FindAsync()

So what is the difference between SaveChanges() and SaveChangesAsync()?
And between Find() and FindAsync()?

在服务器一边,当我们使用异步的方法,我们还需要添加的await 。因此,我不认为这是在服务器端异步的。

On server side, when we use Async methods, we also need to add await. Thus, I don't think it is asynchronous on server side.

这是否只是有助于防止阻塞UI在客户端的浏览器?还是有它们之间的利弊?

Does it only help to prevent the UI blocking on client side browser? Or are there any pros and cons between them?

推荐答案

这需要在远程服务器上做一个动作的任何时候,您的程序生成的请求,将其发送,然后等待一个响应。我将使用的SaveChanges() SaveChangesAsync()作为一个例子,但同样适用于查找() FindAsync()

Any time that you need to do an action on a remote server, your program generates the request, sends it, then waits for a response. I will use SaveChanges() and SaveChangesAsync() as an example but the same applies to Find() and FindAsync().

假设你有一个List <$那你需要添加到您的数据库100+项目C $ C> myList中。要插入,你的函数将看起来像这样:

Say you have a list myList of 100+ items that you need to add to your database. To insert that, your function would look something like so:

using(var context = new MyEDM())
{
    context.MyTable.AddRange(myList);
    context.SaveChanges();
}



首先创建和实例 MyEDM ,添加列表 myList中 MyTable的,然后调用的SaveChanges( )以保存更改到数据库。它的工作原理要如何,这些记录得到COMMITED,但你的程序不能做任何事情,直到提交结束。这取决于你犯什么需要很长的时间。如果您提交更改的记录,实体必须提交这些一次(我曾经有一个保存需要2分钟更新)!

First you create and instance of MyEDM, add the list myList to the table MyTable, then call SaveChanges() to persist the changes to the database. It works how you want, the records get commited, but your program cannot do anything else until the commit finishes. This can take a long time depending on what you are committing. If you are committing changes to the records, entity has to commit those one at a time (I once had a save take 2 minutes for updates)!

要解决这个问题, ,你可以做两件事情之一。第一个是你可以启动一个新的线程来处理插入。虽然这将释放调用线程继续执行,您创建了一个新的线程只是要坐在那里等待。没有必要为开销,这就是异步的await 模式解决了什么。

To solve this problem, you could do one of two things. The first is you can start up a new thread to handle the insert. While this will free up the calling thread to continue executing, you created a new thread that is just going to sit there and wait. There is no need for that overhead, and this is what the async await pattern solves.

有关I / O opperations,等待很快成为你最好的朋友。考虑从上面的代码段,我们可以修改它是:使用(VAR上下文=新MyEDM())$ B

For I/O opperations, await quickly becomes your best friend. Taking the code section from above, we can modify it to be:

using(var context = new MyEDM())
{
    Console.WriteLine("Save Starting");
    context.MyTable.AddRange(myList);
    await context.SaveChangesAsync();
    Console.WriteLine("Save Complete");
}



这是一个非常小的变化,但也有对效率产生深远的影响和你的代码的性能。那么会发生什么?该代码的开头是一样的,你创建 MyEDM 的一个实例和添加 myList中 MyTable的。但是,当你调用等待context.SaveChangesAsync(),代码执行返回到调用的功能!所以,当你正在等待所有这些记录提交时,你的代码可以继续执行。说包含上述代码的功能有公共异步任务SaveRecords(列表< MyTable的> saveList)签署,调用函数可能看起来像这样:

It is a very small change, but there are profound effects on the efficiency and performance of your code. So what happens? The begining of the code is the same, you create an instance of MyEDM and add your myList to MyTable. But when you call await context.SaveChangesAsync(), the execution of code returns to the calling function! So while you are waiting for all those records to commit, your code can continue to execute. Say the function that contained the above code had the signature of public async Task SaveRecords(List<MyTable> saveList), the calling function could look like this:

public async Task MyCallingFunction()
{
    Console.WriteLine("Function Starting");
    Task saveTask = SaveRecords(GenerateNewRecords());

    for(int i = 0; i < 1000; i++){
        Console.WriteLine("Continuing to execute!");
    }

    await saveTask;
    Console.Log("Function Complete");
}



为什么你会有这样的功能,我不知道,但它输出展示了如何异步的await 的作品。首先让我们去了会发生什么。

Why you would have a function like this, I don't know, but what it outputs shows how async await works. First lets go over what happens.

执行进入 MyCallingFunction 功能启动然后保存启动被写入到控制台,则函数 SaveChangesAsync()被调用。在这一点上,执行返回到 MyCallingFunction 键,进入循环写入继续执行多达1000次。当 SaveChangesAsync() finnishes,执行返回到 SaveRecords 功能,那么写保存完整到控制台。一旦 SaveRecords 一切都完成后,程序将继续执行 MyCallingFunction 右键是它是当 SaveChangesAsync( )结束。困惑?下面是一个例子输出:

Execution enters MyCallingFunction, Function Starting then Save Starting gets written to the console, then the function SaveChangesAsync() gets called. At this point, execution returns to MyCallingFunction and enters the for loop writing 'Continuing to Execute' up to 1000 times. When SaveChangesAsync() finnishes, execution returns to the SaveRecordsfunction, writing Save Complete to the console. Once everything in SaveRecords completes, execution will continue in MyCallingFunction right were it was when SaveChangesAsync() finished. Confused? Here is an example output:


Function Starting
Save Starting
Continuing to execute!
Continuing to execute!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Save Complete!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Function Complete!



也许

Or maybe:


Function Starting
Save Starting
Continuing to execute!
Continuing to execute!
Save Complete!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Function Complete!

这是异步的await 的美丽,你的代码可以继续运行,而你在等待的东西来完成。在现实中,你将有一个功能更喜欢以此作为你的调用函数:

That is the beauty of async await, your code can continue to run while you are waiting for something to finish. In reality, you would have a function more like this as your calling function:

public async Task MyCallingFunction()
{
    List<Task> myTasks = new List<Task>();
    myTasks.Add(SaveRecords(GenerateNewRecords()));
    myTasks.Add(SaveRecords2(GenerateNewRecords2()));
    myTasks.Add(SaveRecords3(GenerateNewRecords3()));
    myTasks.Add(SaveRecords4(GenerateNewRecords4()));

    await Task.WhenAll(myTasks.ToArray());
}



在这里,你有四个不同的保存记录的功能去的在同一时间的。 MyCallingFunction 将完成速度快了很多使用异步的await 那么,如果个人 SaveRecords 函数的调用系列。

Here, you have four different save record functions going at the same time. MyCallingFunction will complete a lot faster using async await then if the individual SaveRecords functions were called in series.

这是我还没有尚未触及的一件事是等待关键词。这样做是从执行到任何工作你正在等待公司完成停止当前功能。所以在的情况下,原始的 MyCallingFunction ,行功能齐全将不会被写入到控制台,直到 SaveRecords 函数完成。

The one thing that I have not touched on yet is the await keyword. What this does is stop the current function from executing until whatever Task you are awaiting completes. So in the case of the original MyCallingFunction, the line Function Complete will not be written to the console until the SaveRecords function finishes.

长话短说,如果你必须使用异步的await <选项/ code>,你应该就会大大增加您的应用程序的性能。

Long story short, if you have an option to use async await, you should as it will greatly increase the performance of your application.

这篇关于实体框架的SaveChanges()与SaveChangesAsync()和find()与FindAsync()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆