【发布时间】:2021-07-14 18:48:27
【问题描述】:
我想使用 Automapper 10.1.1 的投影为 EFCore 5 创建一个查询,该查询将有条件地包含关联。 如果我要在 select 语句中写这个,我会做以下事情:
_dbContext.Employees
.Select(x => new EmployeeDto()
{
Id = x.Id,
Contract = includeContract ? new ContractDto()
{
Id = x.Contract.Id
} : null
})
.FirstAsync();
我是这样尝试的:
型号
//Source
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Contract ActiveContract { get; set; }
}
public class Contract
{
public int Id { get; set; }
public DateTimeOffset StartDate { get; set; }
public DateTimeOffset EndDate { get; set; }
public Employee Employee { get; set; }
public int EmployeeId { get; set; }
}
//Destination
public class EmployeeDto
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public ContractDto ActiveContract { get; set; }
}
public class ContractDto
{
public int Id { get; set; }
public DateTimeOffset StartDate { get; set; }
public DateTimeOffset EndDate { get; set; }
}
AutoMapper 配置文件
public class EmployeeProfile : Profile
{
public EmployeeProfile()
{
bool includeContract = false;
CreateMap<Employee, EmployeeDto>()
.ForMember(x => x.ActiveContract, opt => opt.MapFrom(x => includeContract ? x.ActiveContract : null));
}
}
我尝试了default(Contract) 和(Contract)null 而不是null,它们会产生相同的结果。
我还有一个合同映射,只是一个简单的<Contract, ContractDto>。
查询
bool includeContract = someCondition;
var result = await _dbContext.Employees
.ProjectTo<EmployeeDto>(_mapper.ConfigurationProvider, new { includeContract })
.FirstAsync(x => x.id == id);
我的预期结果是,除非 includeContract 设置为 true,否则我将返回一个合同为空的 EmployeeDto。
但是如果includeContract 为假,则会抛出以下错误:
System.InvalidOperationException: Expression 'NULL' in SQL tree does not have type mapping assigned
产生的查询表达式:
Compiling query expression:
'DbSet<Employee>()
.Select(dtoEmployee => new EmployeeDto{
Age = dtoEmployee.Age,
Id = dtoEmployee.Id,
Name = dtoEmployee.Name,
ActiveContract = null == null ? null : new ContractDto{
Id = null.Id,
StartDate = null.StartDate,
EndDate = null.EndDate
}
}
)
.First(x => x.Id == __id_0)'
我知道这可以通过在 ConvertUsing 中显式定义表达式来实现,但我希望尽可能避免写出我的整个 DTO。
【问题讨论】:
-
@LucianBargaoanu 这似乎实现了我的目标!我唯一不清楚的部分(来自文档)是我需要在每个成员上设置
ExplicitExpansion。
标签: .net-core entity-framework-core automapper