在实体框架中,我可以在将属性添加到 Select 方法时显式加载属性,如下所示:

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();

现在,工作时间创建以下SELECT查询:

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'

而Workhours2创建查询:

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'

工厂是这样的:

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();
}

为什么将查询提取到不同的类,从而提取到方法时,查询会有所不同?

推荐答案

你需要返回Func<WorkHour, WorkHourLookupDto>类型的Expression(接受WorkHour,返回WorkHourLookupDto).

为此不需要函数,您可以将其放入静态字段或属性中.

private static Expression<Func<WorkHour, WorkHourLookupDto>> _createLookUpDto =
    workHour => new()
    {
        Id = workHour.Id,
        StartTime = workHour.StartTime,
        EndTime = workHour.EndTime,
        RecreationInMinutes = workHour.RecreationInMinutes,
        TotalWorkHoursInMinutes = workHour.TotalWorkHoursInMinutes,
        Customer = _customerFactory.CreateMiniDto(workHour.Customer),
        Description = workHour.Description
    };

private static Expression<Func<Customer, CustomerMiniDto>> _createMiniDto = 
    customer =>
    {
        if(customer != null)
            return new()
            {
                Id = customer.Id,
                Name = customer.Name
            };

        return new();
    }
}

现在只需直接传递表达式即可.

var workhours2 = dbContext.WorkHours
    .Select(_createLookUpDto)
    .ToList();

.net相关问答推荐

如何处理以用户为中心的CSP现时值?(uc-lock.bundle.js)

F#:跨度、提升和底部类型(或缺乏)

仅在有换行符时捕获分隔符之间的所有文本

使属性只能通过绑定的 Editor(component) 编辑

如何确定计时器是否正在运行?

xunit Assert.ThrowsAsync() 不能正常工作?

在 .NET 反射中使用 GetProperties() 和 BindingFlags.DeclaredOnly

为什么 Any() 不适用于 c# null 对象

每 X 秒执行一次指定函数

如何在任务栏顶部全屏显示 Windows 窗体?

发布版本中的 Debug.WriteLine

如何删除只读文件?

使用多个 MemoryCache 实例

如何使用 NUnit(或可能使用另一个框架)测试异步方法?

哪个更快:清除集合或实例化新的

ILookup 接口与 IDictionary

C# - 你如何停止计时器?

Guid.Parse() 或 new Guid() - 有什么区别?

绑定在代码隐藏中定义的对象

序列化一个可为空的 int