提问人:guirms 提问时间:11/9/2023 更新时间:11/9/2023 访问量:72
如何使用 .Select() 在 .NET 中使用不同类型的列表属性映射对象
How to use .Select() to map an object with list properties of different types in .NET
问:
我正在使用 .NET 7,并且我有一个需要映射到此 DTO 的实体框架查询:
public record MachineScheduleDataDto
{
public int MachineScheduleId { get; set; }
public required ICollection<MachineOperationDto> MachineOperationsDto { get; set; }
}
我的问题是我不知道如何映射属性,一旦它是一个 ICollection 并且有一个不同的类类型来映射它。MachineOperationsDto
EF 查询:
var test = _typedContext
.AsNoTracking()
.Include(m => m.MachineOperations!
.Where(m =>
m.InsertedAt.Date <= endDate.Date &&
m.EndTime <= endDate.TimeOfDay &&
m.InsertedAt.Date >= startDate.Date &&
m.StartTime >= startDate.TimeOfDay))
.ThenInclude(m => m.EggQuantities)
.Where(m =>
diffDays.Contains(m.WeekDay) &&
m.MachineOperations!.Any() &&
m.InitialProductionTime <= startDate.TimeOfDay &&
m.FinalProductionTime >= startDate.TimeOfDay)
.OrderBy(m => m.MachineScheduleId)
.Select(m => new MachineScheduleDataDto
{
MachineScheduleId = m.MachineScheduleId,
MachineOperationsDto = // Error because m.MachineOperation has the type "MachineOperation" and the MachineOperationsDto has the type "MachineOperationDto"
});
我将用于制作地图的模型:
public class MachineOperation : BaseModel
{
public int MachineOperationId { get; set; }
public EMachineStatus MachineStatus { get; set; }
public EDevStatus DevStatus { get; set; }
public TimeSpan StartTime { get; set; }
public TimeSpan EndTime { get; set; }
#region Relationships
public required virtual MachineSchedule MachineSchedule { get; set; }
#endregion
}
The DTO:
public record MachineOperationDto
{
public int MachineOperationId { get; set; }
public EMachineStatus MachineStatus { get; set; }
public virtual required MachineScheduleDataDto MachineScheduleDto { get; set; }
}
PS:我无法使用自动映射器,因为包含中的过滤器被自动映射器忽略,请参阅此处
答:
1赞
Svyatoslav Danyliv
11/9/2023
#1
通过以下方式投影所有内容Select
var test = _typedContext
.Where(m =>
diffDays.Contains(m.WeekDay) &&
m.MachineOperations!.Any() &&
m.InitialProductionTime <= startDate.TimeOfDay &&
m.FinalProductionTime >= startDate.TimeOfDay)
.OrderBy(m => m.MachineScheduleId)
.Select(m => new MachineScheduleDataDto
{
MachineScheduleId = m.MachineScheduleId,
MachineOperationsDto = m.MachineOperations!
.Where(mo =>
mo.InsertedAt.Date <= endDate.Date &&
mo.EndTime <= endDate.TimeOfDay &&
mo.InsertedAt.Date >= startDate.Date &&
mo.StartTime >= startDate.TimeOfDay)
.Select(mo => new MachineOperationDto
{
... // other properties
})
.ToList()
})
.ToList();
评论
0赞
Lucian Bargaoanu
11/9/2023
docs.automapper.org/en/latest/......
0赞
Svyatoslav Danyliv
11/9/2023
@LucianBargaoanu,如果此查询不使用 AutoMapper,此链接应该告诉我什么?这是常规的 Eager Loading 查询。
0赞
Lucian Bargaoanu
11/9/2023
它说你怎么做,你说你不能使用它:)ProjectTo
0赞
Svyatoslav Danyliv
11/9/2023
@LucianBargaoanu,您可以根据参数使用过滤器吗?这是无用的情况。ProjectTo
ProjectTo
0赞
Lucian Bargaoanu
11/9/2023
docs.automapper.org/en/latest/......
评论
MachineOperationsDto = new MachineOperationsDto { ... }
但请注意,这将有相同的“问题”——它忽略了 的,您需要将过滤逻辑(从 include)移动到语句中。Select
Include
Select
MachineOperationsDto = m.MachineOperation.Where(...).Select(x => new MachineOperationsDto { ... })
ProjectTo