EF Core 2.2实体嵌套投影

时间:2019-04-17 12:53:19

标签: c# .net-core entity-framework-core projection ef-core-2.2

我有三个相关的实体m = df['value'] < threshold df1 = df[~m].append(df.loc[m, ['value']].sum().rename('Z')) print (df1) value lab A 50 B 35 C 8 Z 7 AB,其中CA的父级,而BB的父级C

    public class A
    {
        public int Id { get; set; }
        public B B { get; set; }
    }

    public class B
    {
        public int Id { get; set; }
        public C C { get; set; }
    }

    public class C
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

以上实体具有自己的DTO模型,其中包含FromEntity方法和Projection

    public class ADto
    {
        public int Id { get; set; }
        public BDto BDto { get; set; }

        public static Expression<Func<A, ADto>> Projection
        {
            get
            {
                return x => new ADto
                {
                    Id = x.Id,
                    BDto = BDto.FromEntity(x.B)
                };
            }
        }
    }
    public class BDto
    {
        public int Id { get; set; }
        public CDto CDto { get; set; }

        public static Expression<Func<B, BDto>> Projection
        {
            get
            {
                return x => new BDto
                {
                    Id = x.Id,
                    CDto = CDto.FromEntity(x.C)
                };
            }
        }

        public static BDto FromEntity(B entity)
        {
            return Projection.Compile().Invoke(entity);
        }
    }
    public class CDto
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public static Expression<Func<C, CDto>> Projection
        {
            get
            {
                return x => new CDto
                {
                    Id = x.Id,
                    Name = x.Name
                };
            }
        }

        public static CDto FromEntity(C entity)
        {
            return Projection.Compile().Invoke(entity);
        }
    }

然后我像这样使用投影:

_context.A.Where(x = x.Id == id).Select(ADto.Projection).FirstOrDefault();

我当前所有尝试都以CDto方法的FromEntity中的异常结束,因为该实体为null,因此无法调用投影。

  

System.NullReferenceException:'对象引用未设置为对象的实例。'

有没有办法链接更多嵌套的投影?

我知道我可以使用:

    public class ADto
    {
        public int Id { get; set; }
        public BDto BDto { get; set; }

        public static Expression<Func<A, ADto>> Projection
        {
            get
            {
                return x => new ADto
                {
                    Id = x.Id,
                    BDto = new BDto()
                    {
                        Id = x.B.Id,
                        CDto = new CDto()
                        {
                            Id = x.B.C.Id,
                            Name = x.B.C.Name
                        }
                    }
                };
            }
        }
    }

但是我想在一个地方管理投影,因为实际的类太复杂了。

1 个答案:

答案 0 :(得分:0)

由于易用性和内置的依赖项注入,我在.NET Core项目中使用Automapper已有一段时间了。它可以处理嵌套的对象映射。

从PM安装:

Install-Package AutoMapper
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

在Startup.cs中的ConfigureServices方法中注册:

services.AddAutoMapper(typeof(Startup));

创建一个类来保留您的映射,例如MappingProfile.cs使用自动映射器中的配置文件,您可以定义映射。

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<A, ADto>();
        CreateMap<B, BDto>();
        CreateMap<C, CDto>();
    }
}

上面的映射告诉自动映射器该实体可以映射到DTO。

在您的控制器中,您可以注入IMapper

private readonly IMapper _mapper;

public MyController(IMapper mapper)
{
    _mapper = mapper;
}

和如下所示的映射值:

var dto = _mapper.Map<A>(a); // Map object to dto, which will map nested objects.