EF Core 2.2 Вложенная проекция сущностей - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть три связанных объекта A, B и C, где A является родителем B, а B является родителем 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 методе, потому что сущность нулевая и, следовательно, проекция не может быть вызвана.

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 голосов
/ 17 апреля 2019

Я довольно давно использую Automapper в проектах .NET Core из-за простоты использования и встроенного внедрения зависимостей.Может обрабатывать сопоставления вложенных объектов.

Установка из PM:

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

Регистрация в Startup.cs, метод ConfigureServices:

services.AddAutoMapper(typeof(Startup));

Создание класса для храненияваши сопоставления, например, MappingProfile.cs с использованием профиля от automapper, вы можете определить сопоставления.

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

Приведенное выше сопоставление сообщает autopper, что сущность может быть сопоставлена ​​с 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...