No entityframework, posso carregar explicitamente as propriedades ao adicioná-las ao método select, assim:
var workhours = dbContext.WorkHours
.Select(w => new WorkHourLookupDto()
{
Id = w.Id,
StartTime = w.StartTime,
EndTime = w.EndTime,
RecreationInMinutes = w.RecreationInMinutes,
TotalWorkHoursInMinutes = w.TotalWorkHoursInMinutes,
Customer = new CustomerMiniDto
{
Id = w.Customer.Id,
Name = w.Customer.Name
},
Description = w.Description
})
.ToList();
var workhours2 = dbContext.WorkHours
.Select(w => _factory.CreateLookUpDto(w))
.ToList();
Agora o workhours cria a seguinte consulta de seleção:
exec sp_executesql N'SELECT [w].[Id], [w].[StartTime], [w].[EndTime], [w].[RecreationInMinutes], [w].[CompanyId], [w].[Created], [w].[CreatedBy], [w].[CustomerId], [w].[Description], [w].[LastModified], [w].[LastModifiedBy], [w].[UserId], [t].[Id], [t].[Name]
FROM [WorkHours] AS [w]
INNER JOIN (
SELECT [c].[Id], [c].[Name]
FROM [Customers] AS [c]
WHERE [c].[CompanyId] = @__ef_filter__CompanyId_2
) AS [t] ON [w].[CustomerId] = [t].[Id]
WHERE ([w].[CompanyId] = @__ef_filter__CompanyId_0) AND ([w].[UserId] = @__ef_filter__p_1)',N'@__ef_filter__CompanyId_2 nvarchar(4000),@__ef_filter__CompanyId_0 nvarchar(4000),@__ef_filter__p_1 uniqueidentifier',@__ef_filter__CompanyId_2=N'3AD04E77-9654-4BBB-A8E8-4DE1335A7516',@__ef_filter__CompanyId_0=N'3AD04E77-9654-4BBB-A8E8-4DE1335A7516',@__ef_filter__p_1='8220F8B8-720D-42E8-9357-2256470EA206'
E workhours2 cria a consulta:
exec sp_executesql N'SELECT [w].[Id], [w].[CompanyId], [w].[Created], [w].[CreatedBy], [w].[CustomerId], [w].[Description], [w].[EndTime], [w].[LastModified], [w].[LastModifiedBy], [w].[RecreationInMinutes], [w].[StartTime], [w].[UserId]
FROM [WorkHours] AS [w]
WHERE ([w].[CompanyId] = @__ef_filter__CompanyId_0) AND ([w].[UserId] = @__ef_filter__p_1)',N'@__ef_filter__CompanyId_0 nvarchar(4000),@__ef_filter__p_1 uniqueidentifier',@__ef_filter__CompanyId_0=N'3AD04E77-9654-4BBB-A8E8-4DE1335A7516',@__ef_filter__p_1='8220F8B8-720D-42E8-9357-2256470EA206'
A fábrica é assim:
public WorkHourLookupDto CreateLookUpDto(WorkHour workHour)
{
return new()
{
Id = workHour.Id,
StartTime = workHour.StartTime,
EndTime = workHour.EndTime,
RecreationInMinutes = workHour.RecreationInMinutes,
TotalWorkHoursInMinutes = workHour.TotalWorkHoursInMinutes,
Customer = _customerFactory.CreateMiniDto(workHour.Customer),
Description = workHour.Description
};
}
public CustomerMiniDto CreateMiniDto(Customer customer)
{
if(customer != null)
return new()
{
Id = customer.Id,
Name = customer.Name
};
return new();
}
Por que a consulta difere ao extraí-la para uma classe diferente, portanto, método?
Você precisa retornar um
Expression
tipo,Func<WorkHour, WorkHourLookupDto>
ou seja, leva umWorkHour
e retorna umWorkHourLookupDto
.Você não precisa de uma função para isso, pode colocá-la em um campo ou propriedade estática.
Agora você simplesmente passa a expressão diretamente.