且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

EF Core-使用Automapper从OData返回映射的多对多关系

更新时间:2023-02-15 18:07:48

常规设置


要使扩展正常工作,您需要允许 $ expand 查询选项。像这样明确配置:

General Setup

To make expansions work, you need to allow for the $expand query option to be used. Configure it explicitly like so:

private IEdmModel GetEdmModel()
{
    var builder = new ODataConventionModelBuilder();

    builder.EntitySet<EstimateDto>(nameof(MyContext.Estimates))
        .EntityType
        .Expand(); // <-- allow expansion

    builder.EntitySet<TypeDto>(nameof(MyContext.Types))
        .EntityType
        .Expand(); // <-- allow expansion

    builder.EntitySet<SubTypeDto>(nameof(MyContext.SubTypes));
    
    return builder.GetEdmModel();
}

您还需要更新AutoMapper映射,以使查询成功映射到DTO:

You will also need to update your AutoMapper map, to allow the queries to be successfully mapped to a DTOs:

public class AutoMapperConfig : Profile
{
    public AutoMapperConfig()
    {
        CreateMap<Estimate, EstimateDto>()
            .ForMember(
                dto => dto.Types,
                opt => opt.MapFrom(x => x.EstimateTypes.Select(y => y.Type)));

        // The following mapping is needed for expansion to work:
        CreateMap<EstimateTypeRel, TypeDto>()
            .ForMember(
                dto => dto.SubTypes,
                opt => opt.MapFrom(x => x.Type));

        CreateMap<Type, TypeDto>()
            .ForMember(
                dto => dto.SubTypes,
                opt => opt.MapFrom(x => x.SubTypes.Select(y => y.SubType)));

        CreateMap<SubTypeRel, SubTypeDto>();
    }
}

设置该配置后,至少有两种可能的解决方案问题,具体取决于您的要求:

With that configuration being setup, there are at least two possible solutions to this issue, depending on your requirements:

如果仅要扩展 Types ,您需要通过添加来更改AutoMapper映射。where(z => z!= null)子句,因为异常告诉您,集合中不允许 null 值,但是OData包含未扩展的 SubType的值实体:

If you only want to expand Types, you will need to change your AutoMapper mappings by adding a .Where(z => z != null) clause, because as the exception tells you, null values are not allowed in collections, but OData includes them for the non-expanded SubType entities:

public class AutoMapperConfig : Profile
{
    public AutoMapperConfig()
    {
        CreateMap<Estimate, EstimateDto>()
            .ForMember(
                dto => dto.Types,
                opt => opt.MapFrom(
                    x => x.EstimateTypes.Select(y => y.Type)
                        .Where(z => z != null))); // <-- filter out null values

        CreateMap<EstimateTypeRel, TypeDto>()
            .ForMember(
                dto => dto.SubTypes,
                opt => opt.MapFrom(x => x.Type));

        CreateMap<Type, TypeDto>()
            .ForMember(
                dto => dto.SubTypes,
                opt => opt.MapFrom(
                    x => x.SubTypes.Select(y => y.SubType)
                        .Where(z => z != null))); // <-- filter out null values

        CreateMap<SubTypeRel, SubTypeDto>();
    }
}

然后您可以使用以下查询:

Then you can use the following query:

https://localhost:5001/odata/Estimates(1)?$expand=Types


B)同时扩展 SubTypes


另一种方法是扩展 SubTypes 属性,因此可以正确填充集合。要将DTO映射的属性扩展到多个级别,请在查询字符串中使用 $ expand 查询选项,如下所示:

B) Also expand SubTypes

The alternative is to expand the SubTypes property as well, so the collection can be properly filled. To expand DTO mapped properties over multiple levels, use the $expand query option in your query string like so:

https://localhost:5001/odata/Estimates(1)?$expand=Types($expand=SubTypes)