以下代码导致Value cannot be null. (Parameter 'source')异常.它是由.ProjectTo引起的,更具体地说,它是由DisciplineDto中的DisciplineHours引起的.很难说是什么原因造成的,但我该如何追溯呢?

它可能是像smt一样的.ThenInclude(discipline => discipline.DisciplineHours).

失败:学业进度表.应用学科.查询.GetDisciplinesByFlowIdQuery[0]

using Response = List<DisciplineDto>;

public class GetDisciplinesByFlowIdQuery : IRequest<Response>
{
    public int FlowId { get; set; }
}

public class GetDisciplinesByFlowIdQueryHandler : IRequestHandler<GetDisciplinesByFlowIdQuery, Response>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public GetDisciplinesByFlowIdQueryHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public Task<Response> Handle(GetDisciplinesByFlowIdQuery request, CancellationToken cancellationToken)
    {
        var flow = _context.Flows
            .Include(f => f.Disciplines)
            .SingleOrDefault(x => x.Id == request.FlowId);

        if (flow == null)
        {
            throw new NotFoundException(nameof(Flow), request.FlowId);
        }

        var result = flow.Disciplines
            .AsQueryable()
            .ProjectTo<DisciplineDto>(_mapper.ConfigurationProvider)
            .ToList();

        return Task.FromResult(result);
    }
}
public class DisciplineDto : IMapFrom<Discipline>
{
    public int Id { get; set; }

    public string ShortName { get; set; }

    public string FullName { get; set; }

    public string DisciplineCode { get; set; }

    public int SemesterNumber { get; set; }

    public bool IsRequired { get; set; }

    public string CurriculumCode { get; set; }

    public int CurriculumVersion { get; set; }

    public DepartmentDto Department { get; set; }
    public PeriodDto Period { get; set; }
    public List<DisciplineHourDto> DisciplineHours { get; set; } // Caused by this line
}

public class Discipline
{
    public int Id { get; set; }
    public string ShortName { get; set; }
    public string FullName { get; set; }
    public string DisciplineCode { get; set; }
    public int SemesterNumber { get; set; }
    public bool IsRequired { get; set; }
    public string CurriculumCode { get; set; }
    public int CurriculumVersion { get; set; }

    public int DepartmentId { get; set; }
    public Department Department { get; set; }
    
    public int PeriodId { get; set; }
    public Period Period { get; set; }

    public List<Flow> Flows { get; set; }
    public List<DisciplineHour> DisciplineHours { get; set; }
    public List<ClassActivity> ClassActivities { get; set; }
}

public class Flow
{
    public int Id { get; set; }
    public int PeriodId { get; set; }
    public Period Period { get; set; }

    public List<Discipline> Disciplines { get; set; }
    public List<Subgroup> Subgroups { get; set; }
    public List<ClassActivity> ClassActivities { get; set; }
}

public class DisciplineHour
{
    public int DisciplineId { get; set; }
    public Discipline Discipline { get; set; }

    public int ClassActivityTypeId { get; set; }
    public ClassActivityType ClassActivityType { get; set; }

    public decimal Hours { get; set; }
}

public class DisciplineHourDto : IMapFrom<DisciplineHour>
{
    public int DisciplineId { get; set; }

    public int ClassActivityTypeId { get; set; }

    public decimal Hours { get; set; }

    public string DisciplineName { get; set; }

    public string ClassActivityTypeName { get; set; }

    public string FullName { get; set; }

    public void Mapping(Profile profile)
    {
        profile.CreateMap<DisciplineHour, DisciplineHourDto>()
            .ForMember(dto => dto.DisciplineName, opt => opt.MapFrom(sh => sh.Discipline.FullName))
            .ForMember(dto => dto.ClassActivityTypeName, opt => opt.MapFrom(sh => sh.ClassActivityType.ShortName))
            .ForMember(dto => dto.FullName, opt => opt.MapFrom(sh => $"{sh.ClassActivityType.FullName} {sh.Discipline.ShortName}"));
    }
}

推荐答案

出现错误是因为SQL查询没有加载Discipline.DisciplineHours属性,EF Core也没有根据需要为您延迟加载属性.

使用automapper时,您必须在从数据库检索到所有数据后,决定是在sql查询级别上进行项目还是在内存中进行映射.

当您从投影的根实体开始时,为sql查询编写投影变得更容易.因此,不要以_context.Flows开始查询,而是以_context.Disciplines开始查询,并找到一个逻辑上与原始查询条件等价的条件.在具体化数据之前,将查询投影到所需的DTO,如

var result = _context.Disciplines
    .Where(d => d.Flows.Any(f => f.Id == request.FlowId))
    .ProjectTo<DisciplineDto>(_mapper.ConfigurationProvider)
    .ToList();

这仅在Automapper以不需要任何客户端功能的方式配置时有效.否则,您需要首先将整个模型加载到内存中.这可以用eager loading_context.Flows.Include(x => x.Disciplines).ThenInclude(y => y.DisciplineHours)...来完成,直到加载了所有需要的数据.

如果对象图很复杂,无法完成即时加载,那么您也可以先部分加载数据,然后在单独的查询中加载更多部分.查看https://stackoverflow.com/a/40068336/5265292了解更多详细信息.

Csharp相关问答推荐

在依赖性注入和继承之间进行 Select

Blazor:类型或命名空间名称Components在命名空间中不存在''

使用yaml将Azure函数代码部署到FunctionApp插槽时出现问题(zip未找到)

有没有一种方法可以防止在编译时在MicrosoftC或非单线程上下文中调用方法?

为什么EF Core 6会针对null验证Count(*)?

使用客户端密钥为Fabric Rest API生成令牌

限制特定REST API不被访问,但部署代码

使用Audit.EntityFramework,我如何将外键的值设置为相关实体上的属性?

无法将生产环境的AppDbContext设置替换为用于集成测试的内存数据库

异步等待Foreach循环中的ConfigureAWait(FALSE)执行什么操作?

为什么此名称不再被识别?名称不存在于当前上下文中?

在扩展方法中,IEnumerable<;T>;不会转换为IEumerable<;T&>

在同一个捕获中可以有多种类型的异常吗?

当我手动停止和关闭系统并打开时,Windows服务未启动

Azure函数正在返回值列表,但该列表在Chrome中显示为空

如何更改Datagridview行标题

通过mini kube中的远程调试Pod与从emoteProcessPickerScript中解析错误输出的代码错误进行比较

如何对构建在Clean架构和CQRS之上的控制器进行单元测试?

无法对包含字符串的列进行排序.请与实体框架联接

使用';UnityEngineering.Random.Range()';的IF语句仅适用于极高的最大值