到目前为止,我的列表上有很多数据要加载。当我使用普通(同步)方式加载数据时,加载所有数据大约需要20秒。我做了这种异步方法,现在我需要大约7秒钟来加载。 我想知道是否有一种方法可以加快它的速度,例如,打开屏幕后立即加载前20张卡,然后执行其他所有操作?到目前为止,这是我的代码。
public async Task<List<CardObject>> GetCardsAsync()
{
using (var context = new MyCARDEntities())
{
return await context.Card
.Include(f => f.Person)
.Include(k => k.CardType)
.Where(arg => arg.LastAction != "D" && arg.PERSON_ID != null)
.Select(k => new CardObject()
{
Id = k.Id,
UID = k.UID,
Person = new PersonBasicObject()
{
Id = k.PersonBasicObject.Id,
OIB = k.PersonBasicObject.OIB,
Name = k.PersonBasicObject.Name,
LastName = k.PersonBasicObject.LastName
}
})
.ToListAsync();
}
}
这是在viewModel中
private async void LoadCards()
{
var cards = await repKartica.GetCardsAsync();
CardLst = new ObservableCollection<CardObject>(cards);
}
private ObservableCollection<CardObject> _CardLst;
public ObservableCollection<CardObject> CardLst
{
get => _CardLst;
set
{
_CardLst= value;
RaisePropertyChanged(() => CardLst);
}
}
答案 0 :(得分:0)
使方法异步并不能使方法更快,它只是允许方法放弃执行线程以允许其他代码运行。这可以使代码更具响应性,但不会更快地检索特定数据。
首先,如果可以避免加载大量数据,则不是一个好主意。客户是否需要一次查看所有全部数据,或者一次可以将其分页到20张卡片的页面中?如果它是或可以分页的,则考虑使用分页集合,该集合可以查询特定数据页(利用.Skip()
和.Take()
),一次只收回20条左右的记录(可见)页面更改。
下一步是查看正在执行的查询。对数据库运行探查器,例如ExpressProfiler,并捕获EF正在运行的SQL。在企业管理器中执行这些查询的副本以获取执行计划,并查看是否有索引建议。
其他提示:使用.Select()
时不需要使用.Include()
。 Select将生成查询以自动从相关实体中提取。
PersonBasicObject和CardObject是您的实体定义吗?如果是这样,那么这些实体中有多少个字段将未被此Select填充?理想情况下,您应该使用专用的视图模型,而不要传递实体。通过使用Select()
填充实体来有选择地填充数据,就意味着它不是实体的完整表示,从而构成了不是实体的实体。由于变量仍会占用内存但没有填充,因此效率可能很低,并且会产生误导并导致错误,因为您将拥有期望实体的代码,并且可能会被调用/重用,但随后却要处理“真实的”完整实体相对于这样加载的不完整实体。实体的唯一目的应该是代表数据状态,而不是为视图状态传输。