async/await 中的多个查询(错误:IEnumerable 不包含 ToListAsync())

本文关键字:错误 IEnumerable 包含 ToListAsync 查询 await async | 更新日期: 2023-09-27 17:57:05

我想分享一下,我浏览了其他类似的帖子,但建议的解决方案对我不起作用,这就是我创建一个单独的线程的原因。我正在尝试使用实体框架中的异步编程来联接这两个结果。我有三种方法,如下所示:

该方法PreprocessAppointment()等待其他两个方法GetApptTask()GetZoneTask()

public async void PreprocessAppointment()
        {
            var task_1 = GetApptTask();
            var task_2 = GetZoneTask();
            await Task.WhenAll(task_1, task_2);
        }

该方法GetApptTask()不会给出任何错误。

public async Task<IEnumerable<appointments>> GetApptTask(){
            var result = db.appointments.Where(d => d.appt_client_id == 15 && d.customer_id == 68009);
            return await result.ToListAsync();

        }

该方法GetZoneTask()给出以下错误。 IEnumerable <zones> does not contain definition for ToListAsync() .

public async Task <IEnumerable<zones>> GetZoneTask()
        {
            var result = db.zones.Where(d => d.zone_client_id == "15").AsEnumerable().Distinct<zones>(new zones.Comparer());
            return await result.ToListAsync();
        }

我无法找出可能导致此错误的原因。我也为下面的appointmentszones附加了模型结构。除了字段之外,模型之间的唯一区别是zonesComparer类的定义。

区域.cs

public class zones
    {
        [Column(Order=0),Key]
        [StringLength(50)]
        public string zone_client_id { get; set; }
        //public int zone_client_id { get; set; }
        [Column(Order = 1), Key]
        [StringLength(5)]
        public string zip { get; set; }

        [StringLength(50)]
        public string zone { get; set; }
        public class Comparer : IEqualityComparer<zones>
        {
            public bool Equals(zones x, zones y)
            {
                return x.zone_client_id == y.zone_client_id
                     && x.zip == y.zip
                     && x.zone == y.zone;
            }
            public int GetHashCode(zones obj)
            {
                return obj.zone_client_id.GetHashCode() ^
                      obj.zip.GetHashCode() ^
                      obj.zone.GetHashCode();   
            }
        }
    }

预约.cs

 public  partial class appointments
    {
        public int appt_client_id { get; set; }
        public int customer_id { get; set; }
        [Key]
        public int appt_id { get; set; }
        public DateTime appt_date_time { get; set; }
        [StringLength(200)]
        public string recording_uri { get; set; }
        public DateTime time_stamp { get; set; }
        [Required]
        [StringLength(20)]
        public string appt_status { get; set; }
        [Required]
        [StringLength(5)]
        public string appt_type { get; set; }
}

async/await 中的多个查询(错误:IEnumerable 不包含 ToListAsync())

ToListAsync()仅适用于IQueryable<T>,当您通过AsEnumerable()将其转换为IEnumerable<T>时,您将失去调用它的能力。

因为一旦你做了AsEnumerable()无论如何你都在使用内存中的集合,只需在这一点上将其作为一个列表。

var allZones = await db.zones.Where(d => d.zone_client_id == "15").ToListAsync().ConfigureAwait(false);
return allZones.Distinct<zones>(new zones.Comparer()).ToList();

最后一个.ToList()是可选的。如果不这样做,并且多次枚举返回的 IEnumerable,则将多次运行Distinct。做一个额外的.ToList(),使它"记住"Distinct的结果,而不是重新计算它。

因为 ToListAsync() 只适用于 IQueryable,所以当你通过 AsEnumerable() 将其转换为 IEnumerable 时,你就失去了调用它的能力。您可以致电 .AsQueryable() 在 IEnumerable 序列上,它将返回 IQueryable。

例如:

private async Task<List<MyModelType>> GetAsyncListFromIEnumerable(
  List<MyModelIEnumerableType> mylist, 
  DateTime startDate, 
  DateTime endDate)
{
  var result = from e in mylist
               where e.StartDate >= startDate 
               && e.EndDate <= endDate
               select new MyModelIEnumerableType
               {
                 // Set of the properties here
               };
  return await result.AsQueryable().ToListAsync();
}

GetApptTask 方法中,返回行处的结果是一个IQueryable,其中ToListAsync定义了扩展方法。

GetZoneTask的调用具有实现IQueryable到未定义扩展方法ToListAsync IEnumerableAsEnumerable

public async Task<IEnumerable<appointments>> GetApptTask()
{
    var result = db.appointments.Where(d => d.appt_client_id == 15 && d.customer_id == 68009);
    return await result.ToListAsync();  // result was an IQueryable here
}
public async Task <IEnumerable<zones>> GetZoneTask()
{
    var result = db.zones.Where(d => d.zone_client_id == "15")
                         .AsEnumerable()
                         .Distinct<zones>(new zones.Comparer());
    return await result.ToListAsync();   // here result is an IEnumerable because of the above call to AsEnumerable
}

正如张伯伦提到的@Scott ToListAsync() 适用于

智商;

但你可以使用

来自结果()

方法代替这个。

public async Task<IEnumerable<appointments>> GetApptTask()
{
   var result = db.appointments.Where(d => d.appt_client_id == 15 && d.customer_id == 68009);
   return await Task.FromResult(result);
 }