【问题标题】:How to call store procedures with async and await in C#如何在 C# 中使用 async 和 await 调用存储过程
【发布时间】:2016-01-15 21:51:49
【问题描述】:

我正在使用 Visual Studio 2015 社区版和 MVC 5,实体框架 6。我刚刚学会了如何使用 async 和 await 进行异步调用。

现在在我的项目中,我只有 CRUD 操作,并且对于所有操作,我都编写了存储过程,除了调用存储过程之外,我的 API 中没有更多的业务逻辑。所以我使用 async 和 await 来调用存储过程。

但是这样做,我得到了错误,

'int' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)

我的代码是,

 [HttpPost]
        public async Task<IHttpActionResult> AddContactEmails(Contacts data)
        {
            using (JodoDataEntities DB = new JodoDataEntities())
            {
                int Result = await DB.AddContacts(data.userId, data.data);
                return Ok();
            }
        }

我的存储过程非常简单,我从中返回任何东西,仍然 EF 将其作为 int 返回类型。

ALTER PROCEDURE [dbo].[AddContacts]
    @userId nvarchar(128),
    @contacts nvarchar(MAX)
AS
BEGIN
    SET NOCOUNT ON;
    if not exists(select top 1 * from Contacts where userId = @userId)
    begin
        insert into Contacts (userId, contacts) VALUES (@userId, @contacts)
    end
END

EF 代码(自动生成),

 public virtual int AddContacts(string userId, string contacts)
        {
            var userIdParameter = userId != null ?
                new ObjectParameter("userId", userId) :
                new ObjectParameter("userId", typeof(string));

            var contactsParameter = contacts != null ?
                new ObjectParameter("contacts", contacts) :
                new ObjectParameter("contacts", typeof(string));

            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AddContacts", userIdParameter, contactsParameter);
        }

1)。为什么我在调用方法时收到此错误?

2)。我需要在哪里进行更改才能使其正常工作?

3)。所以当我的 API 中只有 SP 调用时,我真的需要使用 async 和 await 吗?

【问题讨论】:

  • 由于您的方法不可等待,如果您认为需要使用 async/await,则必须将它们包装在 Task.Run 之类的东西中。

标签: asp.net asp.net-mvc-5 async-await task-parallel-library entity-framework-6.1


【解决方案1】:

如果返回Task&lt;int&gt;

DB.AddContacts(...);

然后this简单地返回一个int

await DB.AddContacts(...);

所以Result 变量的类型应该是int,而不是Task&lt;int&gt;


编辑:我刚刚注意到您的问题中AddContacts() 的定义。这不是async 方法,所以不能等待。您的代码中没有 async 操作。只需完全删除 asyncawait 尝试,这是同步代码...

int Result = DB.AddContacts(...);

顺便说一句,这是个坏主意:

catch (Exception ex)
{
    throw ex;
}

它基本上是在丢弃有用的调试信息。只需完全删除 try/catch 构造,并让最初抛出它的操作抛出异常。

【讨论】:

  • 写完后,int Result = await (DB.AddContacts(data.userId, data.data)); .....给我错误,我们不能从异步方法返回int。它必须作废,task 或 task.
  • @KevalPatel:我刚刚注意到您的问题中AddContacts() 的定义。这……不是async。所以你不能await它。像普通方法一样调用就行了,这段代码中没有async
  • 我已经改变了一些有问题的东西,请检查我的 AddContactEmails()。 AddContacts() 是由实体框架自动生成的。你想让我让它异步吗?
  • @KevalPatel:我不确定你现在想要完成什么。此代码中似乎没有任何异步 I/O 操作。因此,使用这些操作的方法没有理由是异步的。如果 EF 代码有其操作的 async 版本,那么您可以通过使用 async 方法调用 那些
  • 我只是想进行异步调用,所以我正在使用async和await,我还在学习使用async await。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2020-10-24
相关资源
最近更新 更多