我想分享一下,我浏览了其他类似的帖子,但建议的解决方案对我不起作用,这就是我创建一个单独的线程的原因。我正在尝试使用实体框架中的异步编程来联接这两个结果。我有三种方法,如下所示:
该方法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();
}
我无法找出可能导致此错误的原因。我也为下面的appointments
和zones
附加了模型结构。除了字段之外,模型之间的唯一区别是zones
中Comparer
类的定义。
区域.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; }
}
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
IEnumerable
的AsEnumerable
。
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);
}