【问题标题】:The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier'await' 运算符只能在异步 lambda 表达式中使用。考虑用 'async' 修饰符标记这个 lambda 表达式
【发布时间】:2019-02-15 12:17:46
【问题描述】:

在以下 LinQ 查询以获取电话号码时,我正在调用另一个异步方法 GetAspNetUserPhoneNumberByAccountId,这会引发此错误

错误 CS4034 'await' 运算符只能在异步 lambda 表达式中使用。考虑用 'async' 修饰符标记这个 lambda 表达式。

有人知道吗?

 var fullAppointment = await Task.Run(() => Context.AppointmentDetail
     .Where(u =>
     u.StartDateTime >= startdatetime
      && u.EndDateTime <= enddatetime

      )
       .Select(x => new Contracts.CalenderModel2()
        {
          StatusId = (Contracts.Enum.EnumWOStatus)x.Status,
          FName = x.Appointment != null ? x.Appointment.Customer.Account.FName : "",
          LName = x.Appointment != null ? x.Appointment.Customer.Account.LName : "",
          **PrimaryPhone = x.Appointment != null ?
          (await _userRepository.GetAspNetUserPhoneNumberByAccountId( x.Appointment.Customer.AccountId))**
          : "",
          Year = x.Appointment != null && x.Appointment.Vehicle != null ? x.Appointment.Vehicle.MakeYear.Year : 0,
          Make = x.Appointment != null && x.Appointment.Vehicle != null ? x.Appointment.Vehicle.VehicleMaker.MakerName : "",
          Model = x.Appointment != null && x.Appointment.Vehicle != null ? x.Appointment.Vehicle.VehicleModel.Model : "",
          AppointmentId = x.AppointmentId,
          JobEndDateTime = x.EndDateTime,
          JobStartDateTime = x.StartDateTime,
          ColorCategory = x.AppointmentType.ColorCategory,

          SalesRepersentativeUserId =
(x.Appointment != null && x.Appointment.Customer.CustomerBillTo.Count > 0)
              ? x.Appointment.Customer.CustomerBillTo.FirstOrDefault().BillToId : Guid.Empty,

          FullAppointmentDetail = new Contracts.FullAppointmentDetail
          {
            BayId = x.BayId,
            BayName = x.WorkArea != null ? x.WorkArea.BayName : "",
            WorkTypeId = x.WorkTypeId,
            WorkTypeName = x.WorkType != null ? x.WorkType.WorkTypeName : "",
            JobId = x.Appointment != null && x.Appointment.Job != null ? x.Appointment.Job.Id : Guid.Empty,
            JobIdInt = x.Appointment != null && x.Appointment.Job != null ? x.Appointment.Job.JobIdInt : 0,
            AssigneeUserId = x.AssigneeUserId,
            WorkOrderId = x.WorkOrders.FirstOrDefault() != null ? x.WorkOrders.FirstOrDefault().Id : Guid.Empty
          }

        })
        .ToList());

GetAspNetUserPhoneNumberByAccountId 的定义如下

public async Task<string> GetAspNetUserPhoneNumberByAccountId(Guid accountId)
{
  var phone = await Task.Run(() => _Context.Account.Where(ac => ac.Id.Equals(accountId))
   .Join(_Context.AspNetUsers, ac => ac.AspNetUserId, u => u.Id, (ac, u) => new 
   {
     PhoneNumber = u.PhoneNumber,

   }).FirstOrDefault());

  return phone!=null?phone.ToString():"";
}

【问题讨论】:

  • 为什么在这两种方法中都使用Task.Run?关于具体问题,本站有plenty of duplicates。但我认为你首先不应该在这里使用async
  • 为什么需要等待?该方法不是异步的,所以它会自动等待。
  • 除了关于您为什么使用Task.Run 以及是否需要等待的问题。只需致电Task.Run(async () =&gt; {… 即可摆脱此错误
  • @Knoop 我认为您实际上还需要将async 添加到Select 的lambda 中。然后,您有一个返回 IEnumerable&lt;Task&lt;T&gt;&gt; 的查询,您必须使用 Task.WhenAll on。
  • @CharlesMager 你是对的。所有包含等待操作的匿名函数都应该是异步的。为了完成,看起来像这样:.Select(async x =&gt;…

标签: c# entity-framework linq


【解决方案1】:

我同意 cmets 中的人的观点,即您不需要在此查询中使用异步方法。此外,此查询不会优化。对于 Where 条件中的每个项目,您将查询到 DB。如果你有很多数据,数据库的性能会下降。我认为在这种情况下对数据库进行 2 次查询要好得多。获取AppointmentDetail 和获取所有帐户的另一个查询。并且两个查询调用都是异步的。然后将其与您的 Contracts.CalenderModel2 类结合起来。

它将更具可读性并且工作速度更快。 并且不要使用 Task.Run();

【讨论】:

  • 我知道了,感谢您的评论。
猜你喜欢
  • 2014-01-02
  • 2016-02-08
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 2016-06-14
相关资源
最近更新 更多