我有以下 EF 查询,大约需要 20 秒才能返回约 100k 行。如果我在 select 语句中删除“地址”和“联系人”子查询(如果您这么称呼它们),则大约需要 2 秒才能返回。是否有更有效的方法来创建包含与员工关联的地址和联系人列表的 Employee 对象?
return await (from account in _databaseContext.Accounts
join client in _databaseContext.Clients on account.AddressClientID equals client.ClientId
where client.EffectiveTo == null
&& client.ClientType.Equals("PERSON")
&& account.EffectiveTo == null
&& account.Status.Equals("INFORCE")
select new Employee
{
Id = account.AccountId,
ClientId = client.ClientId,
FirstName = client.GivenNames,
LastName = client.Surname,
Gender = client.Gender,
Addresses = client.ClientAddresses.Where(x => x.EffectiveTo == null)
.Select(x => AddressFactory.Create(x)).ToList(),
Contacts = client.ClientContacts.Where(x => x.EffectiveTo == null && (x.ContactType == "EMAIL" || x.ContactType == "MOBILE"))
.OrderBy(y => y.EffectiveFrom)
.Select(z => ContactFactory.Create<Employee>(client, z)).ToList(),
DateOfBirth = client.DateOfBirth
}).ToListAsync(cancellationToken);
这几乎肯定是使用这些工厂方法在
Select
内部进行的客户端评估。相反,将其更改为显式工作以填充所需的模型,并理想地定义简化的视图模型或 DTO 来表示您需要的结构,仅使用您需要的列,这可以改进索引选项/使用并减少数据量等正在组成。
即手动组合对象而不是使用工厂方法。 EF 无法将对
XFactory.Create()
的调用转换为 SQL,因此最终可能会将大量额外数据提取到内存中以传递给这些工厂调用。相反,请使用 Select
手动创建类的实例。 AFAIK 这些类应该有 EF 可以访问的默认构造函数和设置器。